summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/char/GNUmakefile17
-rw-r--r--src/char/Makefile6
-rw-r--r--src/char/char.c529
-rw-r--r--src/char/char.h3
-rw-r--r--src/char/int_guild.c118
-rw-r--r--src/char/int_guild.h1
-rw-r--r--src/char/int_party.c148
-rw-r--r--src/char/int_party.h1
-rw-r--r--src/char/int_pet.c47
-rw-r--r--src/char/int_pet.h1
-rw-r--r--src/char/int_storage.c168
-rw-r--r--src/char/int_storage.h1
-rw-r--r--src/char/inter.c65
-rw-r--r--src/char/inter.h1
-rw-r--r--src/char_sql/GNUmakefile20
-rw-r--r--src/char_sql/Makefile12
-rw-r--r--src/char_sql/char.c4177
-rw-r--r--src/char_sql/char.h11
-rw-r--r--src/char_sql/int_guild.c665
-rw-r--r--src/char_sql/int_guild.h1
-rw-r--r--src/char_sql/int_party.c245
-rw-r--r--src/char_sql/int_party.h1
-rw-r--r--src/char_sql/int_pet.c72
-rw-r--r--src/char_sql/int_pet.h1
-rw-r--r--src/char_sql/int_storage.c195
-rw-r--r--src/char_sql/int_storage.h1
-rw-r--r--src/char_sql/inter.c139
-rw-r--r--src/char_sql/inter.h8
-rw-r--r--src/char_sql/itemdb.c18
-rw-r--r--src/char_sql/itemdb.h2
-rw-r--r--src/char_sql/make.sh3
-rw-r--r--src/char_sql/strlib.h10
-rw-r--r--src/common/GNUmakefile14
-rw-r--r--src/common/Makefile33
-rw-r--r--src/common/buffer.h18
-rw-r--r--src/common/core.c250
-rw-r--r--src/common/core.h11
-rw-r--r--src/common/db.c203
-rw-r--r--src/common/db.h25
-rw-r--r--src/common/dll.h25
-rw-r--r--src/common/grfio.c251
-rw-r--r--src/common/grfio.h3
-rw-r--r--src/common/lock.c44
-rw-r--r--src/common/malloc.c510
-rw-r--r--src/common/malloc.h66
-rw-r--r--src/common/mmo.h78
-rw-r--r--src/common/nullpo.h11
-rw-r--r--src/common/showmsg.c125
-rw-r--r--src/common/showmsg.h93
-rw-r--r--src/common/socket.c672
-rw-r--r--src/common/socket.h32
-rw-r--r--src/common/strlib.c (renamed from src/char_sql/strlib.c)45
-rw-r--r--src/common/strlib.h (renamed from src/login_sql/strlib.h)8
-rw-r--r--src/common/timer.c290
-rw-r--r--src/common/timer.h12
-rw-r--r--src/common/utils.c16
-rw-r--r--src/common/utils.h18
-rw-r--r--src/ladmin/GNUmakefile14
-rw-r--r--src/ladmin/Makefile6
-rw-r--r--src/ladmin/ladmin.c70
-rw-r--r--src/ladmin/md5calc.c6
-rw-r--r--src/lib/zconf_win32.h279
-rw-r--r--src/lib/zlib_win32.h893
-rw-r--r--src/login/GNUmakefile13
-rw-r--r--src/login/Makefile7
-rw-r--r--src/login/login.c549
-rw-r--r--src/login/login.h9
-rw-r--r--src/login/md5calc.c6
-rw-r--r--src/login_sql/GNUmakefile18
-rw-r--r--src/login_sql/Makefile14
-rw-r--r--src/login_sql/char_int.c512
-rw-r--r--src/login_sql/char_int.h2
-rw-r--r--src/login_sql/login.c1720
-rw-r--r--src/login_sql/login.h124
-rw-r--r--src/login_sql/login_int.c376
-rw-r--r--src/login_sql/login_int.h1
-rw-r--r--src/login_sql/md5calc.c6
-rw-r--r--src/login_sql/strlib.c58
-rw-r--r--src/map/GNUmakefile75
-rw-r--r--src/map/Makefile103
-rw-r--r--src/map/Makefile.win3215
-rw-r--r--src/map/atcommand.c4043
-rw-r--r--src/map/atcommand.h72
-rw-r--r--src/map/battle.c2751
-rw-r--r--src/map/battle.h97
-rw-r--r--src/map/charcommand.c626
-rw-r--r--src/map/charcommand.h9
-rw-r--r--src/map/chat.c16
-rw-r--r--src/map/chrif.c259
-rw-r--r--src/map/chrif.h8
-rw-r--r--src/map/clif.c3552
-rw-r--r--src/map/clif.h33
-rw-r--r--src/map/guild.c313
-rw-r--r--src/map/guild.h4
-rw-r--r--src/map/intif.c169
-rw-r--r--src/map/intif.h6
-rw-r--r--src/map/itemdb.c339
-rw-r--r--src/map/itemdb.h3
-rw-r--r--src/map/log.c397
-rw-r--r--src/map/log.h13
-rw-r--r--src/map/mail.c259
-rw-r--r--src/map/map.c2012
-rw-r--r--src/map/map.h196
-rw-r--r--src/map/mob.c1798
-rw-r--r--src/map/mob.h32
-rw-r--r--src/map/npc.c1028
-rw-r--r--src/map/npc.h16
-rw-r--r--src/map/npc_chat.c502
-rw-r--r--src/map/party.c56
-rw-r--r--src/map/party.h2
-rw-r--r--src/map/path.c86
-rw-r--r--src/map/pc.c3294
-rw-r--r--src/map/pc.h51
-rw-r--r--src/map/pet.c305
-rw-r--r--src/map/pet.h8
-rw-r--r--src/map/script.c1506
-rw-r--r--src/map/script.h24
-rw-r--r--src/map/skill.c8690
-rw-r--r--src/map/skill.h270
-rw-r--r--src/map/status.c5159
-rw-r--r--src/map/status.h271
-rw-r--r--src/map/storage.c207
-rw-r--r--src/map/storage.h2
-rw-r--r--src/map/trade.c395
-rw-r--r--src/map/vending.c21
-rw-r--r--src/tool/Makefile6
-rw-r--r--src/tool/adduser.c96
-rw-r--r--src/tool/backup100
-rw-r--r--src/tool/cgi/addaccount.cgi204
-rw-r--r--src/tool/checkversion85
-rw-r--r--src/tool/convert.c296
-rw-r--r--src/tool/getlogincount122
-rw-r--r--src/tool/ladmin3793
-rw-r--r--src/tool/mapcheck.sh34
-rw-r--r--src/tool/mapchecker.sh56
-rw-r--r--src/txt-converter/char/GNUmakefile13
-rw-r--r--src/txt-converter/char/Makefile8
-rw-r--r--src/txt-converter/char/char-converter.c177
-rw-r--r--src/txt-converter/char/char.h6
-rw-r--r--src/txt-converter/char/strlib.c66
-rw-r--r--src/txt-converter/char/strlib.h9
-rw-r--r--src/txt-converter/common/mmo.h20
-rw-r--r--src/txt-converter/login/GNUmakefile11
-rw-r--r--src/txt-converter/login/Makefile9
-rw-r--r--src/txt-converter/login/login-converter.c12
-rw-r--r--src/webserver/Changelog.txt3
-rw-r--r--src/webserver/Makefile48
-rw-r--r--src/webserver/Makefile.win35
-rw-r--r--src/webserver/WEBSER~1.layout24
-rw-r--r--src/webserver/Webserver.dev97
-rw-r--r--src/webserver/Webserver.layout38
-rw-r--r--src/webserver/conf/webserver-athena.conf36
-rw-r--r--src/webserver/doc/API.txt50
-rw-r--r--src/webserver/doc/README11
-rw-r--r--src/webserver/generate.c38
-rw-r--r--src/webserver/htmlstyle.c51
-rw-r--r--src/webserver/logs.c8
-rw-r--r--src/webserver/main.c208
-rw-r--r--src/webserver/pages/about.c6
-rw-r--r--src/webserver/pages/notdone.c5
-rw-r--r--src/webserver/pages/sample.c24
-rw-r--r--src/webserver/parse.c135
-rw-r--r--src/webserver/webserver.c136
-rw-r--r--src/webserver/webserver.h21
-rw-r--r--src/zlib/FAQ337
-rw-r--r--src/zlib/README126
-rw-r--r--src/zlib/adler32.c74
-rw-r--r--src/zlib/compress.c79
-rw-r--r--src/zlib/crc32.c333
-rw-r--r--src/zlib/crc32.h441
-rw-r--r--src/zlib/deflate.c1502
-rw-r--r--src/zlib/deflate.h325
-rw-r--r--src/zlib/inffast.c305
-rw-r--r--src/zlib/inffast.h11
-rw-r--r--src/zlib/inffixed.h94
-rw-r--r--src/zlib/inflate.c1274
-rw-r--r--src/zlib/inflate.h117
-rw-r--r--src/zlib/inftrees.c328
-rw-r--r--src/zlib/inftrees.h55
-rw-r--r--src/zlib/trees.c1215
-rw-r--r--src/zlib/trees.h128
-rw-r--r--src/zlib/zconf.h326
-rw-r--r--src/zlib/zlib.h1200
-rw-r--r--src/zlib/zutil.c319
-rw-r--r--src/zlib/zutil.h263
185 files changed, 47086 insertions, 21179 deletions
diff --git a/src/char/GNUmakefile b/src/char/GNUmakefile
deleted file mode 100644
index f3164e0ec..000000000
--- a/src/char/GNUmakefile
+++ /dev/null
@@ -1,17 +0,0 @@
-all: char-server
-txt: char-server
-
-COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o ../common/lock.o ../common/malloc.o ../common/showmsg.o
-COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/db.h ../common/lock.h ../common/timer.h ../common/malloc.h ../common/showmsg.h
-char-server: char.o inter.o int_party.o int_guild.o int_storage.o int_pet.o $(COMMON_OBJ)
- $(CC) -o ../../$@ $^
-
-char.o: char.c char.h inter.h int_pet.h $(COMMON_H) ../common/version.h
-inter.o: inter.c inter.h int_party.h int_guild.h int_storage.h int_pet.h char.h $(COMMON_H)
-int_party.o: int_party.c int_party.h inter.h char.h $(COMMON_H)
-int_guild.o: int_guild.c int_guild.h int_storage.h inter.h char.h $(COMMON_H)
-int_storage.o: int_storage.c int_storage.h int_guild.h inter.h char.h $(COMMON_H)
-int_pet.o: int_pet.c int_pet.h inter.h char.h $(COMMON_H)
-
-clean:
- rm -f *.o ../../char-server
diff --git a/src/char/Makefile b/src/char/Makefile
index 0a2009333..aee0e69e2 100644
--- a/src/char/Makefile
+++ b/src/char/Makefile
@@ -1,10 +1,10 @@
all: char-server
txt: char-server
-COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o ../common/lock.o ../common/malloc.o ../common/showmsg.o
-COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/db.h ../common/lock.h ../common/timer.h ../common/malloc.h ../common/showmsg.h
+COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o ../common/obj/db.o ../common/obj/lock.o ../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/strlib.o
+COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/db.h ../common/lock.h ../common/timer.h ../common/malloc.h ../common/showmsg.h ../common/strlib.h
char-server: char.o inter.o int_party.o int_guild.o int_storage.o int_pet.o $(COMMON_OBJ)
- $(CC) -o ../../$@ $>
+ $(CC) -o ../../$@ $> $(LIB_S)
char.o: char.c char.h inter.h int_pet.h $(COMMON_H) ../common/version.h
inter.o: inter.c inter.h int_party.h int_guild.h int_storage.h int_pet.h char.h $(COMMON_H)
diff --git a/src/char/char.c b/src/char/char.c
index 7ad959bd8..73efbc864 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -2,29 +2,39 @@
// original : char2.c 2003/03/14 11:58:35 Rev.1.5
#include <sys/types.h>
-#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
+
+#ifdef _WIN32
+#include <winsock.h>
+typedef long in_addr_t;
+#else
+#include <sys/socket.h>
#include <netinet/in.h>
-#include <sys/time.h>
-#include <time.h>
+#include <arpa/inet.h>
+#include <netdb.h>
#include <sys/ioctl.h>
+#include <sys/time.h>
#include <unistd.h>
+#endif
+
+#include <time.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
-#include <arpa/inet.h>
-#include <netdb.h>
#include <stdarg.h>
+#include "../common/strlib.h"
#include "core.h"
#include "socket.h"
#include "timer.h"
#include "mmo.h"
+#include "db.h"
#include "version.h"
#include "lock.h"
#include "char.h"
#include "showmsg.h"
+#include "buffer.h"
#include "inter.h"
#include "int_pet.h"
@@ -38,9 +48,6 @@
struct mmo_map_server server[MAX_MAP_SERVERS];
int server_fd[MAX_MAP_SERVERS];
-int server_freezeflag[MAX_MAP_SERVERS]; // Map-server anti-freeze system. Counter. 5 ok, 4...0 freezed
-int anti_freeze_enable = 0;
-int ANTI_FREEZE_INTERVAL = 6;
int login_fd, char_fd;
char userid[24];
@@ -49,11 +56,13 @@ char server_name[20];
char wisp_server_name[24] = "Server";
int login_ip_set_ = 0;
char login_ip_str[16];
-int login_ip;
+in_addr_t login_ip;
int login_port = 6900;
int char_ip_set_ = 0;
char char_ip_str[16];
-int char_ip;
+int bind_ip_set_ = 0;
+char bind_ip_str[16];
+in_addr_t char_ip;
int char_port = 6121;
int char_maintenance;
int char_new;
@@ -103,6 +112,7 @@ int char_id_count = 150000;
struct mmo_charstatus *char_dat;
int char_num, char_max;
int max_connect_user = 0;
+int gm_allow_level = 99;
int autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
int start_zeny = 500;
int start_weapon = 1201;
@@ -151,7 +161,7 @@ int char_log(char *fmt, ...) {
fprintf(logfp, RETCODE);
else {
gettimeofday(&tv, NULL);
- strftime(tmpstr, 24, "%d-%m-%Y %H:%M:%S", localtime(&(tv.tv_sec)));
+ strftime(tmpstr, 24, "%d-%m-%Y %H:%M:%S", localtime((const time_t*)&(tv.tv_sec)));
sprintf(tmpstr + 19, ".%03d: %s", (int)tv.tv_usec / 1000, fmt);
vfprintf(logfp, tmpstr, ap);
}
@@ -162,23 +172,6 @@ int char_log(char *fmt, ...) {
return 0;
}
-//-----------------------------------------------------
-// Function to suppress control characters in a string.
-//-----------------------------------------------------
-int remove_control_chars(unsigned char *str) {
- int i;
- int change = 0;
-
- for(i = 0; str[i]; i++) {
- if (str[i] < 32) {
- str[i] = '_';
- change = 1;
- }
- }
-
- return change;
-}
-
//----------------------------------------------------------------------
// Determine if an account (id) is a GM account
// and returns its level (or 0 if it isn't a GM account or if not found)
@@ -235,6 +228,25 @@ char * search_character_name(int index) {
return unknown_char_name;
}
+//-------------------------------------------------
+// Set Character online/offline [Wizputer]
+//-------------------------------------------------
+
+void set_char_online(int char_id, int account_id) {
+ if (login_fd <= 0 || session[login_fd]->eof)
+ return;
+ WFIFOW(login_fd,0) = 0x272b;
+ WFIFOL(login_fd,2) = account_id;
+ WFIFOSET(login_fd,6);
+}
+void set_char_offline(int char_id, int account_id) {
+ if (login_fd <= 0 || session[login_fd]->eof)
+ return;
+ WFIFOW(login_fd,0) = 0x272c;
+ WFIFOL(login_fd,2) = account_id;
+ WFIFOSET(login_fd,6);
+}
+
/*---------------------------------------------------
Make a data line for friends list
--------------------------------------------------*/
@@ -243,7 +255,7 @@ int mmo_friends_list_data_str(char *str, struct mmo_charstatus *p) {
int i;
char *str_p = str;
str_p += sprintf(str_p, "%d", p->char_id);
-
+
for (i=0;i<20;i++)
{
str_p += sprintf(str_p, ",%d,%s", p->friend_id[i],p->friend_name[i]);
@@ -267,9 +279,9 @@ int mmo_char_tostr(char *str, struct mmo_charstatus *p) {
str_p += sprintf(str_p, "%d\t%d,%d\t%s\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d\t%d,%d,%d,%d,%d,%d\t%d,%d"
"\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d,%d"
- "\t%s,%d,%d\t%s,%d,%d,%d\t",
+ "\t%s,%d,%d\t%s,%d,%d,%d,%d,%d,%d\t",
p->char_id, p->account_id, p->char_num, p->name, //
- p->class, p->base_level, p->job_level,
+ p->class_, p->base_level, p->job_level,
p->base_exp, p->job_exp, p->zeny,
p->hp, p->max_hp, p->sp, p->max_sp,
p->str, p->agi, p->vit, p->int_, p->dex, p->luk,
@@ -280,7 +292,7 @@ int mmo_char_tostr(char *str, struct mmo_charstatus *p) {
p->weapon, p->shield, p->head_top, p->head_mid, p->head_bottom,
p->last_point.map, p->last_point.x, p->last_point.y, //
p->save_point.map, p->save_point.x, p->save_point.y,
- p->partner_id);
+ p->partner_id,p->father,p->mother,p->child);
for(i = 0; i < 10; i++)
if (p->memo_point[i].map[0]) {
str_p += sprintf(str_p, "%s,%d,%d", p->memo_point[i].map, p->memo_point[i].x, p->memo_point[i].y);
@@ -329,8 +341,28 @@ int mmo_char_fromstr(char *str, struct mmo_charstatus *p) {
// initilialise character
memset(p, '\0', sizeof(struct mmo_charstatus));
-
- // If it's not char structure of version 1008 and after
+
+ // If it's not char structure of version 1363 and after
+ if ((set = sscanf(str, "%d\t%d,%d\t%[^\t]\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d\t%d,%d,%d,%d,%d,%d\t%d,%d"
+ "\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d,%d"
+ "\t%[^,],%d,%d\t%[^,],%d,%d,%d,%d,%d,%d%n",
+ &tmp_int[0], &tmp_int[1], &tmp_int[2], p->name, //
+ &tmp_int[3], &tmp_int[4], &tmp_int[5],
+ &tmp_int[6], &tmp_int[7], &tmp_int[8],
+ &tmp_int[9], &tmp_int[10], &tmp_int[11], &tmp_int[12],
+ &tmp_int[13], &tmp_int[14], &tmp_int[15], &tmp_int[16], &tmp_int[17], &tmp_int[18],
+ &tmp_int[19], &tmp_int[20],
+ &tmp_int[21], &tmp_int[22], &tmp_int[23], //
+ &tmp_int[24], &tmp_int[25], &tmp_int[26],
+ &tmp_int[27], &tmp_int[28], &tmp_int[29],
+ &tmp_int[30], &tmp_int[31], &tmp_int[32], &tmp_int[33], &tmp_int[34],
+ p->last_point.map, &tmp_int[35], &tmp_int[36], //
+ p->save_point.map, &tmp_int[37], &tmp_int[38], &tmp_int[39],
+ &tmp_int[40], &tmp_int[41], &tmp_int[42], &next)) != 46) {
+ tmp_int[40] = 0; // father
+ tmp_int[41] = 0; // mother
+ tmp_int[42] = 0; // child
+ // If it's not char structure of version 1008 and before 1363
if ((set = sscanf(str, "%d\t%d,%d\t%[^\t]\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d\t%d,%d,%d,%d,%d,%d\t%d,%d"
"\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d,%d"
"\t%[^,],%d,%d\t%[^,],%d,%d,%d%n",
@@ -389,15 +421,20 @@ int mmo_char_fromstr(char *str, struct mmo_charstatus *p) {
}
// Char structure of version 1008+
} else {
+ set+=3;
//printf("char: new char data ver.3\n");
}
- if (set != 43)
+ // Char structture of version 1363+
+ } else {
+ //printf("char: new char data ver.4\n");
+ }
+ if (set != 46)
return 0;
p->char_id = tmp_int[0];
p->account_id = tmp_int[1];
p->char_num = tmp_int[2];
- p->class = tmp_int[3];
+ p->class_ = tmp_int[3];
p->base_level = tmp_int[4];
p->job_level = tmp_int[5];
p->base_exp = tmp_int[6];
@@ -434,6 +471,9 @@ int mmo_char_fromstr(char *str, struct mmo_charstatus *p) {
p->save_point.x = tmp_int[37];
p->save_point.y = tmp_int[38];
p->partner_id = tmp_int[39];
+ p->father = tmp_int[40];
+ p->mother = tmp_int[41];
+ p->child = tmp_int[42];
// Some checks
for(i = 0; i < char_num; i++) {
@@ -574,13 +614,16 @@ int parse_friend_txt(struct mmo_charstatus *p)
char line[1024];
int i,cid=0,temp[20];
FILE *fp;
-
+
// Open the file and look for the ID
fp = fopen(friends_txt, "r");
-
+
+ if(fp == NULL)
+ return 1;
+
while(fgets(line, sizeof(line)-1, fp)) {
-
+
if(line[0] == '/' && line[1] == '/')
continue;
@@ -608,7 +651,7 @@ int parse_friend_txt(struct mmo_charstatus *p)
if (cid == p->char_id)
break;
}
-
+
// No register of friends list
if (cid == 0) {
fclose(fp);
@@ -634,16 +677,11 @@ int mmo_char_init(void) {
FILE *fp;
char_max = 256;
- char_dat = calloc(sizeof(struct mmo_charstatus) * 256, 1);
+ char_dat = (struct mmo_charstatus*)aCalloc(sizeof(struct mmo_charstatus) * 256, 1);
if (!char_dat) {
printf("out of memory: mmo_char_init (calloc of char_dat).\n");
exit(1);
}
- online_chars = calloc(sizeof(struct online_chars) * 256, 1);
- if (!online_chars) {
- printf("out of memory: mmo_char_init (calloc of online_chars).\n");
- exit(1);
- }
for(i = 0; i < char_max; i++)
{
online_chars[i].char_id = -1;
@@ -679,13 +717,13 @@ int mmo_char_init(void) {
if (char_num >= char_max) {
char_max += 256;
- char_dat = realloc(char_dat, sizeof(struct mmo_charstatus) * char_max);
+ char_dat = (struct mmo_charstatus*)aRealloc(char_dat, sizeof(struct mmo_charstatus) * char_max);
if (!char_dat) {
printf("Out of memory: mmo_char_init (realloc of char_dat).\n");
char_log("Out of memory: mmo_char_init (realloc of char_dat)." RETCODE);
exit(1);
}
- online_chars = realloc(online_chars, sizeof(struct online_chars) * char_max);
+ online_chars = (struct online_chars*)aRealloc(online_chars, sizeof(struct online_chars) * char_max);
if (!online_chars) {
printf("Out of memory: mmo_char_init (realloc of online_chars).\n");
char_log("Out of memory: mmo_char_init (realloc of online_chars)." RETCODE);
@@ -699,10 +737,10 @@ int mmo_char_init(void) {
}
ret = mmo_char_fromstr(line, &char_dat[char_num]);
-
+
// Initialize friends list
parse_friend_txt(&char_dat[char_num]); // Grab friends for the character
-
+
if (ret > 0) { // negative value or zero for errors
if (char_dat[char_num].char_id >= char_id_count)
char_id_count = char_dat[char_num].char_id + 1;
@@ -765,7 +803,8 @@ void mmo_char_sync(void) {
int i, j, k;
int lock;
FILE *fp,*f_fp;
- int id[char_num];
+ //int *id = (int *) aMalloc(sizeof(int) * char_num);
+ CREATE_BUFFER(id, int, char_num);
// Sorting before save (by [Yor])
for(i = 0; i < char_num; i++) {
@@ -804,6 +843,8 @@ void mmo_char_sync(void) {
if (fp == NULL) {
printf("WARNING: Server can't not create backup of characters file.\n");
char_log("WARNING: Server can't not create backup of characters file." RETCODE);
+ //aFree(id); // free up the memory before leaving -.- [Ajarn]
+ DELETE_BUFFER(id);
return;
}
for(i = 0; i < char_num; i++) {
@@ -821,9 +862,12 @@ void mmo_char_sync(void) {
mmo_friends_list_data_str(f_line, &char_dat[id[i]]);
fprintf(f_fp, "%s" RETCODE, f_line);
}
-
+
lock_fclose(f_fp, friends_txt, &lock);
-
+
+ //aFree(id);
+ DELETE_BUFFER(id);
+
return;
}
@@ -843,18 +887,18 @@ int make_new_char(int fd, unsigned char *dat) {
int i, j;
struct char_session_data *sd;
- sd = session[fd]->session_data;
+ sd = (struct char_session_data*)session[fd]->session_data;
// remove control characters from the name
dat[23] = '\0';
- if (remove_control_chars(dat)) {
+ if (remove_control_chars((unsigned char *)(char*)dat)) {
char_log("Make new char error (control char received in the name): (connection #%d, account: %d)." RETCODE,
fd, sd->account_id);
return -1;
}
// check lenght of character name
- if (strlen(dat) < 4) {
+ if (strlen((const char*)dat) < 4) {
char_log("Make new char error (character name too small): (connection #%d, account: %d, name: '%s')." RETCODE,
fd, sd->account_id, dat);
return -1;
@@ -896,8 +940,8 @@ int make_new_char(int fd, unsigned char *dat) {
}
for(i = 0; i < char_num; i++) {
- if ((name_ignoring_case != 0 && strcmp(char_dat[i].name, dat) == 0) ||
- (name_ignoring_case == 0 && strcmpi(char_dat[i].name, dat) == 0)) {
+ if ((name_ignoring_case != 0 && strcmp(char_dat[i].name, (const char*)dat) == 0) ||
+ (name_ignoring_case == 0 && strcmpi(char_dat[i].name, (const char*)dat) == 0)) {
char_log("Make new char error (name already exists): (connection #%d, account: %d) slot %d, name: %s (actual name of other char: %d), stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d." RETCODE,
fd, sd->account_id, dat[30], dat, char_dat[i].name, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29], dat[24] + dat[25] + dat[26] + dat[27] + dat[28] + dat[29], dat[33], dat[31]);
return -1;
@@ -909,7 +953,7 @@ int make_new_char(int fd, unsigned char *dat) {
}
}
- if (strcmp(wisp_server_name, dat) == 0) {
+ if (strcmp(wisp_server_name, (const char*)dat) == 0) {
char_log("Make new char error (name used is wisp name for server): (connection #%d, account: %d) slot %d, name: %s (actual name of other char: %d), stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d." RETCODE,
fd, sd->account_id, dat[30], dat, char_dat[i].name, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29], dat[24] + dat[25] + dat[26] + dat[27] + dat[28] + dat[29], dat[33], dat[31]);
return -1;
@@ -917,13 +961,13 @@ int make_new_char(int fd, unsigned char *dat) {
if (char_num >= char_max) {
char_max += 256;
- char_dat = realloc(char_dat, sizeof(struct mmo_charstatus) * char_max);
+ char_dat = (struct mmo_charstatus*)aRealloc(char_dat, sizeof(struct mmo_charstatus) * char_max);
if (!char_dat) {
printf("Out of memory: make_new_char (realloc of char_dat).\n");
char_log("Out of memory: make_new_char (realloc of char_dat)." RETCODE);
exit(1);
}
- online_chars = realloc(online_chars, sizeof(struct online_chars) * char_max);
+ online_chars = (struct online_chars*)aRealloc(online_chars, sizeof(struct online_chars) * char_max);
if (!online_chars) {
printf("Out of memory: make_new_char (realloc of online_chars).\n");
char_log("Out of memory: make_new_char (realloc of online_chars)." RETCODE);
@@ -943,8 +987,8 @@ int make_new_char(int fd, unsigned char *dat) {
char_dat[i].char_id = char_id_count++;
char_dat[i].account_id = sd->account_id;
char_dat[i].char_num = dat[30];
- strcpy(char_dat[i].name, dat);
- char_dat[i].class = 0;
+ strcpy(char_dat[i].name, (const char*)dat);
+ char_dat[i].class_ = 0;
char_dat[i].base_level = 1;
char_dat[i].job_level = 1;
char_dat[i].base_exp = 0;
@@ -994,8 +1038,8 @@ int make_new_char(int fd, unsigned char *dat) {
//----------------------------------------------------
// This function return the name of the job (by [Yor])
//----------------------------------------------------
-char * job_name(int class) {
- switch (class) {
+char * job_name(int class_) {
+ switch (class_) {
case 0: return "Novice";
case 1: return "Swordsman";
case 2: return "Mage";
@@ -1080,7 +1124,7 @@ void create_online_files(void) {
char temp[256]; // to prepare what we must display
time_t time_server; // for number of seconds
struct tm *datetime; // variable for time in structure ->tm_mday, ->tm_sec, ...
- int id[online_players_max];
+ int id[4096];
// don't return here if we display nothing, because server[j].users is updated in the first loop.
@@ -1153,12 +1197,12 @@ void create_online_files(void) {
break;
case 4: // by job (and job level)
for(k = 0; k < players; k++)
- if (char_dat[j].class < char_dat[id[k]].class ||
+ if (char_dat[j].class_ < char_dat[id[k]].class_ ||
// if same job, we sort by job level.
- (char_dat[j].class == char_dat[id[k]].class &&
+ (char_dat[j].class_ == char_dat[id[k]].class_ &&
char_dat[j].job_level < char_dat[id[k]].job_level) ||
// if same job and job level, we sort by job exp.
- (char_dat[j].class == char_dat[id[k]].class &&
+ (char_dat[j].class_ == char_dat[id[k]].class_ &&
char_dat[j].job_level == char_dat[id[k]].job_level &&
char_dat[j].job_exp < char_dat[id[k]].job_exp)) {
for(l = players; l > k; l--)
@@ -1299,7 +1343,7 @@ void create_online_files(void) {
}
// displaying of the job
if (online_display_option & 6) {
- char * jobname = job_name(char_dat[j].class);
+ char * jobname = job_name(char_dat[j].class_);
if ((online_display_option & 6) == 6) {
fprintf(fp2, " <td>%s %d/%d</td>\n", jobname, char_dat[j].base_level, char_dat[j].job_level);
fprintf(fp, "%-18s %3d/%3d ", jobname, char_dat[j].base_level, char_dat[j].job_level);
@@ -1352,8 +1396,9 @@ void create_online_files(void) {
if (players == 0) {
fprintf(fp2, " <p>No user is online.</p>\n");
fprintf(fp, "No user is online.\n");
- // no display if only 1 player
} else if (players == 1) {
+ fprintf(fp2, " <p>%d user is online.</p>\n", players);
+ fprintf(fp, "%d user is online.\n", players);
} else {
fprintf(fp2, " <p>%d users are online.</p>\n", players);
fprintf(fp, "%d users are online.\n", players);
@@ -1433,9 +1478,15 @@ int mmo_char_send006b(int fd, struct char_session_data *sd) {
WFIFOW(fd,j+46) = (p->sp > 0x7fff) ? 0x7fff : p->sp;
WFIFOW(fd,j+48) = (p->max_sp > 0x7fff) ? 0x7fff : p->max_sp;
WFIFOW(fd,j+50) = DEFAULT_WALK_SPEED; // p->speed;
- WFIFOW(fd,j+52) = p->class;
+ WFIFOW(fd,j+52) = p->class_;
WFIFOW(fd,j+54) = p->hair;
- WFIFOW(fd,j+56) = p->weapon;
+
+ // pecopeco knights/crusaders crash fix
+ if (p->class_ == 13 || p->class_ == 21 ||
+ p->class_ == 4014 || p->class_ == 4022)
+ WFIFOW(fd,j+56) = 0;
+ else WFIFOW(fd,j+56) = p->weapon;
+
WFIFOW(fd,j+58) = p->base_level;
WFIFOW(fd,j+60) = p->skill_point;
WFIFOW(fd,j+62) = p->head_bottom;
@@ -1501,9 +1552,9 @@ int char_divorce(struct mmo_charstatus *cs) {
//------------------------------------------------------------
// E-mail check: return 0 (not correct) or 1 (valid). by [Yor]
//------------------------------------------------------------
-int e_mail_check(unsigned char *email) {
+int e_mail_check(char *email) {
char ch;
- unsigned char* last_arobas;
+ char* last_arobas;
// athena limits
if (strlen(email) < 3 || strlen(email) > 39)
@@ -1546,7 +1597,7 @@ int disconnect_player(int accound_id) {
// disconnect player if online on char-server
for(i = 0; i < fd_max; i++) {
- if (session[i] && (sd = session[i]->session_data)) {
+ if (session[i] && (sd = (struct char_session_data*)session[i]->session_data)) {
if (sd->account_id == accound_id) {
session[i]->eof = 1;
return 1;
@@ -1579,7 +1630,7 @@ static int char_delete(struct mmo_charstatus *cs) {
// —£¥
if (cs->partner_id){
// —£¥î•ñ‚ðmap‚É’Ê’m
- char buf[10];
+ unsigned char buf[10];
WBUFW(buf,0) = 0x2b12;
WBUFL(buf,2) = cs->char_id;
WBUFL(buf,6) = cs->partner_id;
@@ -1608,7 +1659,7 @@ int parse_tologin(int fd) {
return 0;
}
- sd = session[fd]->session_data;
+ sd = (struct char_session_data*)session[fd]->session_data;
while(RFIFOREST(fd) >= 2) {
// printf("parse_tologin: connection #%d, packet: 0x%x (with being read: %d bytes).\n", fd, RFIFOW(fd,0), RFIFOREST(fd));
@@ -1641,7 +1692,7 @@ int parse_tologin(int fd) {
return 0;
// printf("parse_tologin 2713 : %d\n", RFIFOB(fd,6));
for(i = 0; i < fd_max; i++) {
- if (session[i] && (sd = session[i]->session_data) && sd->account_id == RFIFOL(fd,2)) {
+ if (session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == RFIFOL(fd,2)) {
if (RFIFOB(fd,6) != 0) {
WFIFOW(i,0) = 0x6c;
WFIFOB(i,2) = 0x42;
@@ -1657,6 +1708,10 @@ int parse_tologin(int fd) {
sd->connect_until_time = (time_t)RFIFOL(fd,47);
// send characters to player
mmo_char_send006b(i, sd);
+ } else if(isGM(sd->account_id) >= gm_allow_level) {
+ sd->connect_until_time = (time_t)RFIFOL(fd,47);
+ // send characters to player
+ mmo_char_send006b(i, sd);
} else {
// refuse connection: too much online players
// printf("count_users(): %d < max_connect_use (%d) -> fail...\n", count_users(), max_connect_user);
@@ -1675,7 +1730,7 @@ int parse_tologin(int fd) {
if (RFIFOREST(fd) < 50)
return 0;
for(i = 0; i < fd_max; i++) {
- if (session[i] && (sd = session[i]->session_data)) {
+ if (session[i] && (sd = (struct char_session_data*)session[i]->session_data)) {
if (sd->account_id == RFIFOL(fd,2)) {
memcpy(sd->email, RFIFOP(fd,6), 40);
if (e_mail_check(sd->email) == 0)
@@ -1688,6 +1743,42 @@ int parse_tologin(int fd) {
RFIFOSKIP(fd,50);
break;
+ // login-server alive packet
+ case 0x2718:
+ if (RFIFOREST(fd) < 2)
+ return 0;
+ RFIFOSKIP(fd,2);
+ break;
+
+ // Receiving authentification from Freya-type login server (to avoid char->login->char)
+ case 0x2719:
+ if (RFIFOREST(fd) < 18)
+ return 0;
+ // to conserv a maximum of authentification, search if account is already authentified and replace it
+ // that will reduce multiple connection too
+ for(i = 0; i < AUTH_FIFO_SIZE; i++)
+ if (auth_fifo[i].account_id == RFIFOL(fd,2))
+ break;
+ // if not found, use next value
+ if (i == AUTH_FIFO_SIZE) {
+ if (auth_fifo_pos >= AUTH_FIFO_SIZE)
+ auth_fifo_pos = 0;
+ i = auth_fifo_pos;
+ auth_fifo_pos++;
+ }
+ //printf("auth_fifo set (auth #%d) - account: %d, secure: %08x-%08x\n", i, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10));
+ auth_fifo[i].account_id = RFIFOL(fd,2);
+ auth_fifo[i].char_id = 0;
+ auth_fifo[i].login_id1 = RFIFOL(fd,6);
+ auth_fifo[i].login_id2 = RFIFOL(fd,10);
+ auth_fifo[i].delflag = 2; // 0: auth_fifo canceled/void, 2: auth_fifo received from login/map server in memory, 1: connection authentified
+ auth_fifo[i].char_pos = 0;
+ auth_fifo[i].connect_until_time = 0; // unlimited/unknown time by default (not display in map-server)
+ auth_fifo[i].ip = RFIFOL(fd,14);
+ //auth_fifo[i].map_auth = 0;
+ RFIFOSKIP(fd,18);
+ break;
+
case 0x2721: // gm reply
if (RFIFOREST(fd) < 10)
return 0;
@@ -1714,7 +1805,7 @@ int parse_tologin(int fd) {
if (acc > 0) {
for (i = 0; i < char_num; i++) {
if (char_dat[i].account_id == acc) {
- int jobclass = char_dat[i].class;
+ int jobclass = char_dat[i].class_;
char_dat[i].sex = sex;
auth_fifo[i].sex = sex;
if (jobclass == 19 || jobclass == 20 ||
@@ -1722,11 +1813,11 @@ int parse_tologin(int fd) {
jobclass == 4042 || jobclass == 4043) {
// job modification
if (jobclass == 19 || jobclass == 20) {
- char_dat[i].class = (sex) ? 19 : 20;
+ char_dat[i].class_ = (sex) ? 19 : 20;
} else if (jobclass == 4020 || jobclass == 4021) {
- char_dat[i].class = (sex) ? 4020 : 4021;
+ char_dat[i].class_ = (sex) ? 4020 : 4021;
} else if (jobclass == 4042 || jobclass == 4043) {
- char_dat[i].class = (sex) ? 4042 : 4043;
+ char_dat[i].class_ = (sex) ? 4042 : 4043;
}
// remove specifical skills of classes 19, 4020 and 4042
for(j = 315; j <= 322; j++) {
@@ -1780,14 +1871,14 @@ int parse_tologin(int fd) {
if (i == MAX_MAP_SERVERS)
char_log("'ladmin': Receiving a message for broadcast, but no map-server is online." RETCODE);
else {
- char buf[128];
- char message[RFIFOL(fd,4) + 1]; // +1 to add a null terminated if not exist in the packet
+ unsigned char buf[128];
+ char message[4096]; // +1 to add a null terminated if not exist in the packet
int lp;
char *p;
memset(message, '\0', sizeof(message));
memcpy(message, RFIFOP(fd,8), RFIFOL(fd,4));
message[sizeof(message)-1] = '\0';
- remove_control_chars(message);
+ remove_control_chars((unsigned char *)message);
// remove all first spaces
p = message;
while(p[0] == ' ')
@@ -1875,7 +1966,7 @@ int parse_tologin(int fd) {
int j, k;
struct char_session_data *sd2;
for (j = 0; j < fd_max; j++) {
- if (session[j] && (sd2 = session[j]->session_data) &&
+ if (session[j] && (sd2 = (struct char_session_data*)session[j]->session_data) &&
sd2->account_id == char_dat[char_num-1].account_id) {
for (k = 0; k < 9; k++) {
if (sd2->found_char[k] == char_num-1) {
@@ -1928,10 +2019,10 @@ int parse_tologin(int fd) {
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
{
- char buf[32000];
+ unsigned char buf[32000];
if (gm_account != NULL)
- free(gm_account);
- gm_account = calloc(sizeof(struct gm_account) * ((RFIFOW(fd,2) - 4) / 5), 1);
+ aFree(gm_account);
+ gm_account = (struct gm_account*)aCalloc(sizeof(struct gm_account) * ((RFIFOW(fd,2) - 4) / 5), 1);
GM_num = 0;
for (i = 4; i < RFIFOW(fd,2); i = i + 5) {
gm_account[GM_num].account_id = RFIFOL(fd,i);
@@ -1950,7 +2041,66 @@ int parse_tologin(int fd) {
RFIFOSKIP(fd,RFIFOW(fd,2));
break;
+ // Receive GM accounts [Freya login server packet by Yor]
+ case 0x2733:
+ // add test here to remember that the login-server is Freya-type
+ // sprintf (login_server_type, "Freya");
+ if (RFIFOREST(fd) < 7)
+ return 0;
+ {
+ unsigned char buf[32000];
+ int new_level = 0;
+ for(i = 0; i < GM_num; i++)
+ if (gm_account[i].account_id == RFIFOL(fd,2)) {
+ if (gm_account[i].level != (int)RFIFOB(fd,6)) {
+ gm_account[i].level = (int)RFIFOB(fd,6);
+ new_level = 1;
+ }
+ break;
+ }
+ // if not found, add it
+ if (i == GM_num) {
+ // limited to 4000, because we send information to char-servers (more than 4000 GM accounts???)
+ // int (id) + int (level) = 8 bytes * 4000 = 32k (limit of packets in windows)
+ if (((int)RFIFOB(fd,6)) > 0 && GM_num < 4000) {
+ if (GM_num == 0) {
+ gm_account = (struct gm_account*)aMalloc(sizeof(struct gm_account));
+ } else {
+ gm_account = (struct gm_account*)aRealloc(gm_account, sizeof(struct gm_account) * (GM_num + 1));
+ }
+ gm_account[GM_num].account_id = RFIFOL(fd,2);
+ gm_account[GM_num].level = (int)RFIFOB(fd,6);
+ new_level = 1;
+ GM_num++;
+ if (GM_num >= 4000) {
+ printf("***WARNING: 4000 GM accounts found. Next GM accounts are not readed.\n");
+ char_log("***WARNING: 4000 GM accounts found. Next GM accounts are not readed." RETCODE);
+ }
+ }
+ }
+ if (new_level == 1) {
+ int len;
+ printf("From login-server: receiving a GM account information (%d: level %d).\n", RFIFOL(fd,2), (int)RFIFOB(fd,6));
+ char_log("From login-server: receiving a GM account information (%d: level %d)." RETCODE, RFIFOL(fd,2), (int)RFIFOB(fd,6));
+ //create_online_files(); // not change online file for only 1 player (in next timer, that will be done
+ // send gm acccounts level to map-servers
+ len = 4;
+ WBUFW(buf,0) = 0x2b15;
+
+ for(i = 0; i < GM_num; i++) {
+ WBUFL(buf, len) = gm_account[i].account_id;
+ WBUFB(buf, len+4) = (unsigned char)gm_account[i].level;
+ len += 5;
+ }
+ WBUFW(buf, 2) = len;
+ mapif_sendall(buf, len);
+ }
+ }
+ RFIFOSKIP(fd,7);
+ break;
+
default:
+ printf("parse_tologin: unknown packet %x! \n", RFIFOW(fd,0));
session[fd]->eof = 1;
return 0;
}
@@ -1960,28 +2110,6 @@ int parse_tologin(int fd) {
return 0;
}
-//--------------------------------
-// Map-server anti-freeze system
-//--------------------------------
-int map_anti_freeze_system(int tid, unsigned int tick, int id, int data) {
- int i;
-
- //printf("Entering in map_anti_freeze_system function to check freeze of servers.\n");
- for(i = 0; i < MAX_MAP_SERVERS; i++) {
- if (server_fd[i] >= 0) {// if map-server is online
- //printf("map_anti_freeze_system: server #%d, flag: %d.\n", i, server_freezeflag[i]);
- if (server_freezeflag[i]-- < 1) { // Map-server anti-freeze system. Counter. 5 ok, 4...0 freezed
- printf("Map-server anti-freeze system: char-server #%d is freezed -> disconnection.\n", i);
- char_log("Map-server anti-freeze system: char-server #%d is freezed -> disconnection." RETCODE,
- i);
- session[server_fd[i]]->eof = 1;
- }
- }
- }
-
- return 0;
-}
-
int parse_frommap(int fd) {
int i, j;
int id;
@@ -2007,6 +2135,14 @@ int parse_frommap(int fd) {
// printf("parse_frommap: connection #%d, packet: 0x%x (with being read: %d bytes).\n", fd, RFIFOW(fd,0), RFIFOREST(fd));
switch(RFIFOW(fd,0)) {
+
+ // map-server alive packet
+ case 0x2718:
+ if (RFIFOREST(fd) < 2)
+ return 0;
+ RFIFOSKIP(fd,2);
+ break;
+
// request from map-server to reload GM accounts. Transmission to login-server (by Yor)
case 0x2af7:
if (login_fd > 0) { // don't send request if no login-server
@@ -2119,8 +2255,6 @@ int parse_frommap(int fd) {
if (RFIFOREST(fd) < 6 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
server[id].users = RFIFOW(fd,4);
- if(anti_freeze_enable)
- server_freezeflag[id] = 5; // Map anti-freeze system. Counter. 5 ok, 4...0 freezed
// remove all previously online players of the server
for(i = 0; i < online_players_max; i++)
if (online_chars[i].server == id) {
@@ -2141,7 +2275,7 @@ int parse_frommap(int fd) {
if (j == online_players_max) {
// create 256 new slots
online_players_max += 256;
- online_chars = realloc(online_chars, sizeof(struct online_chars) * online_players_max);
+ online_chars = (struct online_chars*)aRealloc(online_chars, sizeof(struct online_chars) * online_players_max);
if (!online_chars) {
printf("out of memory: parse_frommap - online_chars (realloc).\n");
exit(1);
@@ -2411,20 +2545,23 @@ int parse_frommap(int fd) {
RFIFOSKIP(fd, RFIFOW(fd,2));
// printf("char: save_account_reg (from map)\n");
break;
- }
- // Map server send information to change an email of an account -> login-server
- case 0x3000:
- if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
+ }
+ // Character disconnected set online 0 [Wizputer]
+ case 0x2b17:
+ if (RFIFOREST(fd) < 6)
return 0;
- if (login_fd > 0) { // don't send request if no login-server
- WFIFOW(login_fd,0) = 0x3000;
- WFIFOW(login_fd,2) = RFIFOW(fd,2);
- WFIFOL(login_fd,4) = RFIFOL(fd,4);
- WFIFOB(login_fd,8) = RFIFOB(fd,8);
- WFIFOSET(login_fd, RFIFOW(fd,2));
- printf("char : change sex -> login %d %d %d \n", RFIFOL(fd,4), RFIFOB(fd,8), RFIFOW(fd,2));
- }
- RFIFOSKIP(fd, RFIFOW(fd,2));
+ //printf("Setting %d char offline\n",RFIFOL(fd,2));
+ set_char_offline(RFIFOL(fd,2),RFIFOL(fd,6));
+ RFIFOSKIP(fd,10);
+ break;
+
+ // Character set online [Wizputer]
+ case 0x2b19:
+ if (RFIFOREST(fd) < 6)
+ return 0;
+ //printf("Setting %d char online\n",RFIFOL(fd,2));
+ set_char_online(RFIFOL(fd,2),RFIFOL(fd,6));
+ RFIFOSKIP(fd,10);
break;
default:
@@ -2513,7 +2650,7 @@ int parse_char(int fd) {
return 0;
}
- sd = session[fd]->session_data;
+ sd = (struct char_session_data*)session[fd]->session_data;
while (RFIFOREST(fd) >= 2) {
cmd = RFIFOW(fd,0);
@@ -2537,7 +2674,7 @@ int parse_char(int fd) {
// if (sd == NULL && cmd != 0x65 && cmd != 0x20b && cmd != 0x187 &&
// cmd != 0x2af8 && cmd != 0x7530 && cmd != 0x7532)
// cmd = 0xffff; // ƒpƒPƒbƒgƒ_ƒ“ƒv‚ð•\ަ‚³‚¹‚é
-
+
switch(cmd){
case 0x20b: //20040622ˆÃ†‰»ragexe‘Ήž
if (RFIFOREST(fd) < 19)
@@ -2555,7 +2692,9 @@ int parse_char(int fd) {
else
printf("Account Logged On; Account ID: %d.\n", RFIFOL(fd,2));
if (sd == NULL) {
- sd = session[fd]->session_data = calloc(sizeof(struct char_session_data), 1);
+ sd = (struct char_session_data*)aCalloc(sizeof(struct char_session_data), 1);
+ session[fd]->session_data = sd;
+
memset(sd, 0, sizeof(struct char_session_data));
memcpy(sd->email, "no mail", 40); // put here a mail without '@' to refuse deletion if we don't receive the e-mail
sd->connect_until_time = 0; // unknow or illimited (not displaying on map-server)
@@ -2742,7 +2881,7 @@ int parse_char(int fd) {
WFIFOW(fd,2+46) = (char_dat[i].sp > 0x7fff) ? 0x7fff : char_dat[i].sp;
WFIFOW(fd,2+48) = (char_dat[i].max_sp > 0x7fff) ? 0x7fff : char_dat[i].max_sp;
WFIFOW(fd,2+50) = DEFAULT_WALK_SPEED; // char_dat[i].speed;
- WFIFOW(fd,2+52) = char_dat[i].class;
+ WFIFOW(fd,2+52) = char_dat[i].class_;
WFIFOW(fd,2+54) = char_dat[i].hair;
WFIFOW(fd,2+58) = char_dat[i].base_level;
@@ -2835,7 +2974,7 @@ int parse_char(int fd) {
int j, k;
struct char_session_data *sd2;
for (j = 0; j < fd_max; j++) {
- if (session[j] && (sd2 = session[j]->session_data) &&
+ if (session[j] && (sd2 = (struct char_session_data*)session[j]->session_data) &&
sd2->account_id == char_dat[char_num-1].account_id) {
for (k = 0; k < 9; k++) {
if (sd2->found_char[k] == char_num-1) {
@@ -2877,7 +3016,7 @@ int parse_char(int fd) {
if (server_fd[i] < 0)
break;
}
- if (i == MAX_MAP_SERVERS || strcmp(RFIFOP(fd,2), userid) || strcmp(RFIFOP(fd,26), passwd)){
+ if (i == MAX_MAP_SERVERS || strcmp((char*)RFIFOP(fd,2), userid) || strcmp((char*)RFIFOP(fd,26), passwd)){
WFIFOB(fd,2) = 3;
WFIFOSET(fd,3);
RFIFOSKIP(fd,60);
@@ -2886,8 +3025,6 @@ int parse_char(int fd) {
WFIFOB(fd,2) = 0;
session[fd]->func_parse = parse_frommap;
server_fd[i] = fd;
- if(anti_freeze_enable)
- server_freezeflag[i] = 5; // Map anti-freeze system. Counter. 5 ok, 4...0 freezed
server[i].ip = RFIFOL(fd,54);
server[i].port = RFIFOW(fd,58);
server[i].users = 0;
@@ -2945,24 +3082,24 @@ int parse_char(int fd) {
// Console Command Parser [Wizputer]
int parse_console(char *buf) {
char *type,*command;
-
- type = (char *)malloc(64);
- command = (char *)malloc(64);
-
+
+ type = (char *)aMalloc(64);
+ command = (char *)aMalloc(64);
+
memset(type,0,64);
memset(command,0,64);
-
+
printf("Console: %s\n",buf);
-
+
if ( sscanf(buf, "%[^:]:%[^\n]", type , command ) < 2 )
sscanf(buf,"%[^\n]",type);
-
+
printf("Type of command: %s || Command: %s \n",type,command);
-
- if(buf) free(buf);
- if(type) free(type);
- if(command) free(command);
-
+
+ if(buf) aFree(buf);
+ if(type) aFree(type);
+ if(command) aFree(command);
+
return 0;
}
@@ -3015,7 +3152,7 @@ int mapif_send(int fd, unsigned char *buf, unsigned int len) {
int send_users_tologin(int tid, unsigned int tick, int id, int data) {
int users = count_users();
- char buf[16];
+ unsigned char buf[16];
if (login_fd > 0 && session[login_fd]) {
// send number of user to login server
@@ -3103,8 +3240,8 @@ int lan_config_read(const char *lancfgName) {
if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2)
continue;
- remove_control_chars(w1);
- remove_control_chars(w2);
+ remove_control_chars((unsigned char *)w1);
+ remove_control_chars((unsigned char *)w2);
if (strcmpi(w1, "lan_map_ip") == 0) { // Read map-server Lan IP Address
h = gethostbyname(w2);
if (h != NULL) {
@@ -3175,8 +3312,8 @@ int char_config_read(const char *cfgName) {
if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2)
continue;
- remove_control_chars(w1);
- remove_control_chars(w2);
+ remove_control_chars((unsigned char *)w1);
+ remove_control_chars((unsigned char *)w2);
if (strcmpi(w1, "userid") == 0) {
memcpy(userid, w2, 24);
} else if (strcmpi(w1, "passwd") == 0) {
@@ -3184,7 +3321,7 @@ int char_config_read(const char *cfgName) {
} else if (strcmpi(w1, "server_name") == 0) {
memcpy(server_name, w2, sizeof(server_name));
server_name[sizeof(server_name) - 1] = '\0';
- printf("%s server has been intialized\n", w2);
+ printf("%s server has been initialized\n", w2);
} else if (strcmpi(w1, "wisp_server_name") == 0) {
if (strlen(w2) >= 4) {
memcpy(wisp_server_name, w2, sizeof(wisp_server_name));
@@ -3208,6 +3345,14 @@ int char_config_read(const char *cfgName) {
sprintf(char_ip_str, "%d.%d.%d.%d", (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
} else
memcpy(char_ip_str, w2, 16);
+ } else if (strcmpi(w1, "bind_ip") == 0) {
+ bind_ip_set_ = 1;
+ h = gethostbyname(w2);
+ if (h != NULL) {
+ printf("Character server binding IP address : %s -> %d.%d.%d.%d\n", w2, (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+ sprintf(bind_ip_str, "%d.%d.%d.%d", (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+ } else
+ memcpy(bind_ip_str, w2, 16);
} else if (strcmpi(w1, "char_port") == 0) {
char_port = atoi(w2);
} else if (strcmpi(w1, "char_maintenance") == 0) {
@@ -3228,6 +3373,10 @@ int char_config_read(const char *cfgName) {
max_connect_user = atoi(w2);
if (max_connect_user < 0)
max_connect_user = 0; // unlimited online players
+ } else if(strcmpi(w1, "gm_allow_level") == 0) {
+ gm_allow_level = atoi(w2);
+ if(gm_allow_level < 0)
+ gm_allow_level = 99;
} else if (strcmpi(w1, "check_ip_flag") == 0) {
check_ip_flag = config_switch(w2);
} else if (strcmpi(w1, "autosave_time") == 0) {
@@ -3296,12 +3445,6 @@ int char_config_read(const char *cfgName) {
online_refresh_html = 1;
} else if(strcmpi(w1,"db_path")==0) {
strcpy(db_path,w2);
- } else if(strcmpi(w1,"anti_freeze_enable")==0){
- anti_freeze_enable = config_switch(w2);
- } else if (strcmpi(w1, "anti_freeze_interval") == 0) {
- ANTI_FREEZE_INTERVAL = atoi(w2);
- if (ANTI_FREEZE_INTERVAL < 5)
- ANTI_FREEZE_INTERVAL = 5; // minimum 5 seconds
} else if (strcmpi(w1, "import") == 0) {
char_config_read(w2);
} else if (strcmpi(w1, "console") == 0) {
@@ -3343,19 +3486,20 @@ void do_final(void) {
}
create_online_files();
- if(online_chars) free(online_chars);
+ if(online_chars) aFree(online_chars);
mmo_char_sync();
inter_save();
- if(gm_account) free(gm_account);
- if(char_dat) free(char_dat);
+ if(gm_account) aFree(gm_account);
+ if(char_dat) aFree(char_dat);
delete_session(login_fd);
delete_session(char_fd);
- for(i = 0; i < fd_max; i++)
- if(session[i] != NULL) free(session[i]);
+ inter_final();
+ exit_dbn();
+ timer_final();
char_log("----End of char-server (normal end with closing of all files)." RETCODE);
}
@@ -3363,21 +3507,23 @@ void do_final(void) {
int do_init(int argc, char **argv) {
int i;
- // a newline in the log...
- char_log("");
- char_log("The char-server starting..." RETCODE);
-
+ SERVER_TYPE = SERVER_CHAR;
char_config_read((argc < 2) ? CHAR_CONF_NAME : argv[1]);
lan_config_read((argc > 1) ? argv[1] : LOGIN_LAN_CONF_NAME);
- if ((naddr_ != 0) && (login_ip_set_ == 0 || char_ip_set_ == 0)) {
+ // a newline in the log...
+ char_log("");
+ // moved behind char_config_read in case we changed the filename [celest]
+ char_log("The char-server starting..." RETCODE);
+
+ if ((naddr_ != 0) && (login_ip_set_ == 0 || char_ip_set_ == 0)) {
// The char server should know what IP address it is running on
// - MouseJstr
int localaddr = ntohl(addr_[0]);
unsigned char *ptr = (unsigned char *) &localaddr;
char buf[16];
sprintf(buf, "%d.%d.%d.%d", ptr[0], ptr[1], ptr[2], ptr[3]);;
- if (naddr_ != 1)
+ if (naddr_ != 1)
printf("Multiple interfaces detected.. using %s as our IP address\n", buf);
else
printf("Defaulting to %s as our IP address\n", buf);
@@ -3386,9 +3532,9 @@ int do_init(int argc, char **argv) {
if (char_ip_set_ == 0)
strcpy(char_ip_str, buf);
- if (ptr[0] == 192 && ptr[1] == 168)
- printf("Firewall detected.. edit lan_support.conf and char_athena.conf");
- }
+ if (ptr[0] == 192 && ptr[1] == 168)
+ printf("Firewall detected.. edit lan_support.conf and char_athena.conf\n");
+ }
login_ip = inet_addr(login_ip_str);
char_ip = inet_addr(char_ip_str);
@@ -3399,7 +3545,7 @@ int do_init(int argc, char **argv) {
}
online_players_max = 256;
- online_chars = calloc(sizeof(struct online_chars) * 256, 1);
+ online_chars = (struct online_chars*)aCalloc(sizeof(struct online_chars) * 256, 1);
if (!online_chars) {
printf("out of memory: do_init (calloc).\n");
exit(1);
@@ -3409,7 +3555,6 @@ int do_init(int argc, char **argv) {
online_chars[i].server = -1;
}
-
mmo_char_init();
update_online = time(NULL);
@@ -3420,12 +3565,15 @@ int do_init(int argc, char **argv) {
set_termfunc(do_final);
set_defaultparse(parse_char);
- char_fd = make_listen_port(char_port);
+ if (bind_ip_set_)
+ char_fd = make_listen_bind(inet_addr(bind_ip_str),char_port);
+ else
+ char_fd = make_listen_bind(INADDR_ANY,char_port);
add_timer_func_list(check_connect_login_server, "check_connect_login_server");
add_timer_func_list(send_users_tologin, "send_users_tologin");
add_timer_func_list(mmo_char_sync_timer, "mmo_char_sync_timer");
-
+
i = add_timer_interval(gettick() + 1000, check_connect_login_server, 0, 0, 10 * 1000);
i = add_timer_interval(gettick() + 1000, send_users_tologin, 0, 0, 5 * 1000);
i = add_timer_interval(gettick() + autosave_interval, mmo_char_sync_timer, 0, 0, autosave_interval);
@@ -3438,13 +3586,6 @@ int do_init(int argc, char **argv) {
if (flush_on)
add_timer_interval(gettick()+10, flush_timer,0,0,flush_time);
-
-
- if(anti_freeze_enable > 0) {
- add_timer_func_list(map_anti_freeze_system, "map_anti_freeze_system");
- i = add_timer_interval(gettick() + 1000, map_anti_freeze_system, 0, 0, ANTI_FREEZE_INTERVAL * 1000); // checks every X seconds user specifies
- }
-
if(console) {
set_defaultconsoleparse(parse_console);
start_console();
@@ -3456,3 +3597,19 @@ int do_init(int argc, char **argv) {
return 0;
}
+
+int char_married(int pl1,int pl2) {
+ if (char_dat[pl1].char_id == char_dat[pl2].partner_id && char_dat[pl2].char_id == char_dat[pl1].partner_id)
+ return 1;
+ else
+ return 0;
+}
+
+int char_child(int parent_id, int child_id) {
+ if (char_dat[parent_id].child == char_dat[child_id].char_id &&
+ ((char_dat[parent_id].char_id == char_dat[child_id].father) ||
+ (char_dat[parent_id].char_id == char_dat[child_id].mother)))
+ return 1;
+ else
+ return 0;
+}
diff --git a/src/char/char.h b/src/char/char.h
index 3ee2f9f6d..78f4f0194 100644
--- a/src/char/char.h
+++ b/src/char/char.h
@@ -24,6 +24,9 @@ int mapif_sendall(unsigned char *buf, unsigned int len);
int mapif_sendallwos(int fd,unsigned char *buf, unsigned int len);
int mapif_send(int fd,unsigned char *buf, unsigned int len);
+int char_married(int pl1,int pl2);
+int char_child(int parent_id, int child_id);
+
int char_log(char *fmt, ...);
extern int autosave_interval;
diff --git a/src/char/int_guild.c b/src/char/int_guild.c
index eb03dd335..9268d9339 100644
--- a/src/char/int_guild.c
+++ b/src/char/int_guild.c
@@ -45,7 +45,7 @@ int inter_guild_tostr(char *str, struct guild *g) {
len += sprintf(str + len, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\t%s\t",
m->account_id, m->char_id,
m->hair, m->hair_color, m->gender,
- m->class, m->lv, m->exp, m->exp_payper, m->position,
+ m->class_, m->lv, m->exp, m->exp_payper, m->position,
((m->account_id > 0) ? m->name : "-"));
}
// –ðE
@@ -138,7 +138,7 @@ int inter_guild_fromstr(char *str, struct guild *g) {
m->hair = tmp_int[2];
m->hair_color = tmp_int[3];
m->gender = tmp_int[4];
- m->class = tmp_int[5];
+ m->class_ = tmp_int[5];
m->lv = tmp_int[6];
m->exp = tmp_int[7];
m->exp_payper = tmp_int[8];
@@ -398,7 +398,7 @@ int inter_guild_init() {
continue;
}
- g = calloc(sizeof(struct guild), 1);
+ g = (struct guild *) aCalloc(sizeof(struct guild), 1);
if(g == NULL){
printf("int_guild: out of memory!\n");
exit(0);
@@ -412,7 +412,7 @@ int inter_guild_init() {
guild_calcinfo(g);
} else {
printf("int_guild: broken data [%s] line %d\n", guild_txt, c);
- free(g);
+ aFree(g);
}
c++;
}
@@ -426,7 +426,7 @@ int inter_guild_init() {
}
while(fgets(line, sizeof(line)-1, fp)) {
- gc = calloc(sizeof(struct guild_castle), 1);
+ gc = (struct guild_castle *) aCalloc(sizeof(struct guild_castle), 1);
if(gc == NULL){
printf("int_guild: out of memory!\n");
exit(0);
@@ -436,7 +436,7 @@ int inter_guild_init() {
numdb_insert(castle_db, gc->castle_id, gc);
} else {
printf("int_guild: broken data [%s] line %d\n", castle_txt, c);
- free(gc);
+ aFree(gc);
}
c++;
}
@@ -445,7 +445,7 @@ int inter_guild_init() {
printf(" %s - making Default Data...\n", castle_txt);
//ƒfƒtƒHƒ‹ƒgƒf[ƒ^‚ðì¬
for(i = 0; i < MAX_GUILDCASTLE; i++) {
- gc = calloc(sizeof(struct guild_castle), 1);
+ gc = (struct guild_castle *) aCalloc(sizeof(struct guild_castle), 1);
if (gc == NULL) {
printf("int_guild: out of memory!\n");
exit(0);
@@ -488,10 +488,28 @@ int inter_guild_init() {
return 0;
}
+int castle_db_final (void *k, void *data, va_list ap)
+{
+ struct guild_castle *gc = (struct guild_castle *) data;
+ if (gc) aFree(gc);
+ return 0;
+}
+int guild_db_final (void *k, void *data, va_list ap)
+{
+ struct guild *g = (struct guild *) data;
+ if (g) aFree(g);
+ return 0;
+}
+void inter_guild_final() {
+ numdb_final(castle_db, castle_db_final);
+ numdb_final(guild_db, guild_db_final);
+ return;
+}
+
struct guild *inter_guild_search(int guild_id) {
struct guild *g;
- g=numdb_search(guild_db, guild_id);
+ g = (struct guild *) numdb_search(guild_db, guild_id);
return g;
}
@@ -577,7 +595,7 @@ int guild_check_empty(struct guild *g) {
numdb_erase(guild_db, g->guild_id);
inter_guild_storage_delete(g->guild_id);
mapif_guild_broken(g->guild_id, 0);
- free(g);
+ aFree(g);
return 1;
}
@@ -656,7 +674,7 @@ int guild_calcinfo(struct guild *g) {
g->next_exp = guild_nextexp(g->guild_lv);
// ƒƒ“ƒoãŒÀiƒMƒ‹ƒhŠg’£“K—pj
- g->max_member = 16 + guild_checkskill(g, GD_EXTENSION) * 2;
+ g->max_member = 16 + guild_checkskill(g, GD_EXTENSION) * 6; //Lupus 2 -> 6
// •½‹ÏƒŒƒxƒ‹‚ƃIƒ“ƒ‰ƒCƒ“l”
g->average_lv = 0;
@@ -713,7 +731,7 @@ int mapif_guild_noinfo(int fd, int guild_id) {
// ƒMƒ‹ƒhî•ñ‚܂Ƃߑ—‚è
int mapif_guild_info(int fd, struct guild *g) {
- unsigned char buf[4 + sizeof(struct guild)];
+ unsigned char buf[16384];
WBUFW(buf,0) = 0x3831;
memcpy(buf + 4, g, sizeof(struct guild));
@@ -765,9 +783,9 @@ int mapif_guild_memberinfoshort(struct guild *g, int idx) {
WBUFL(buf, 2) = g->guild_id;
WBUFL(buf, 6) = g->member[idx].account_id;
WBUFL(buf,10) = g->member[idx].char_id;
- WBUFB(buf,14) = g->member[idx].online;
+ WBUFB(buf,14) = (unsigned char)g->member[idx].online;
WBUFW(buf,15) = g->member[idx].lv;
- WBUFW(buf,17) = g->member[idx].class;
+ WBUFW(buf,17) = g->member[idx].class_;
mapif_sendall(buf, 19);
return 0;
}
@@ -786,15 +804,15 @@ int mapif_guild_broken(int guild_id, int flag) {
}
// ƒMƒ‹ƒh“à”­Œ¾
-int mapif_guild_message(int guild_id, int account_id, char *mes, int len) {
- unsigned char buf[len+12];
+int mapif_guild_message(int guild_id, int account_id, char *mes, int len, int sfd) {
+ unsigned char buf[2048];
WBUFW(buf,0) = 0x3837;
WBUFW(buf,2) = len + 12;
WBUFL(buf,4) = guild_id;
WBUFL(buf,8) = account_id;
memcpy(WBUFP(buf,12), mes, len);
- mapif_sendall(buf, len + 12);
+ mapif_sendallwos(sfd, buf, len + 12);
return 0;
}
@@ -814,7 +832,7 @@ int mapif_guild_basicinfochanged(int guild_id, int type, const void *data, int l
// ƒMƒ‹ƒhƒƒ“ƒoî•ñ•ÏX’Ê’m
int mapif_guild_memberinfochanged(int guild_id, int account_id, int char_id, int type, const void *data, int len) {
- unsigned char buf[len + 18];
+ unsigned char buf[4096];
WBUFW(buf, 0) = 0x383a;
WBUFW(buf, 2) = len + 18;
@@ -860,7 +878,7 @@ int mapif_guild_alliance(int guild_id1, int guild_id2, int account_id1, int acco
// ƒMƒ‹ƒh–ðE•ÏX’Ê’m
int mapif_guild_position(struct guild *g, int idx) {
- unsigned char buf[sizeof(struct guild_position) + 12];
+ unsigned char buf[2048];
WBUFW(buf,0) = 0x383b;
WBUFW(buf,2) = sizeof(struct guild_position) + 12;
@@ -965,7 +983,7 @@ int mapif_parse_CreateGuild(int fd, int account_id, char *name, struct guild_mem
mapif_guild_created(fd, account_id, NULL);
return 0;
}
- g = calloc(sizeof(struct guild), 1);
+ g = (struct guild *) aCalloc(sizeof(struct guild), 1);
if (g == NULL) {
printf("int_guild: CreateGuild: out of memory !\n");
mapif_guild_created(fd, account_id, NULL);
@@ -1005,7 +1023,7 @@ int mapif_parse_CreateGuild(int fd, int account_id, char *name, struct guild_mem
int mapif_parse_GuildInfo(int fd, int guild_id) {
struct guild *g;
- g = numdb_search(guild_db, guild_id);
+ g = (struct guild *) numdb_search(guild_db, guild_id);
if (g != NULL){
guild_calcinfo(g);
mapif_guild_info(fd, g);
@@ -1020,7 +1038,7 @@ int mapif_parse_GuildAddMember(int fd, int guild_id, struct guild_member *m) {
struct guild *g;
int i;
- g = numdb_search(guild_db, guild_id);
+ g = (struct guild *) numdb_search(guild_db, guild_id);
if (g == NULL) {
mapif_guild_memberadded(fd, guild_id, m->account_id, m->char_id, 1);
return 0;
@@ -1046,7 +1064,7 @@ int mapif_parse_GuildLeave(int fd, int guild_id, int account_id, int char_id, in
struct guild *g = NULL;
int i, j;
- g = numdb_search(guild_db, guild_id);
+ g = (struct guild *)numdb_search(guild_db, guild_id);
if (g != NULL) {
for(i = 0; i < MAX_GUILD; i++) {
if (g->member[i].account_id == account_id && g->member[i].char_id == char_id) {
@@ -1085,11 +1103,11 @@ int mapif_parse_GuildLeave(int fd, int guild_id, int account_id, int char_id, in
}
// ƒIƒ“ƒ‰ƒCƒ“/LvXV
-int mapif_parse_GuildChangeMemberInfoShort(int fd, int guild_id, int account_id, int char_id, int online, int lv, int class) {
+int mapif_parse_GuildChangeMemberInfoShort(int fd, int guild_id, int account_id, int char_id, int online, int lv, int class_) {
struct guild *g;
int i, alv, c;
- g = numdb_search(guild_db, guild_id);
+ g = (struct guild *) numdb_search(guild_db, guild_id);
if (g == NULL)
return 0;
@@ -1101,7 +1119,7 @@ int mapif_parse_GuildChangeMemberInfoShort(int fd, int guild_id, int account_id,
if (g->member[i].account_id == account_id && g->member[i].char_id == char_id) {
g->member[i].online = online;
g->member[i].lv = lv;
- g->member[i].class = class;
+ g->member[i].class_ = class_;
mapif_guild_memberinfoshort(g, i);
}
if (g->member[i].account_id > 0) {
@@ -1111,8 +1129,10 @@ int mapif_parse_GuildChangeMemberInfoShort(int fd, int guild_id, int account_id,
if (g->member[i].online)
g->connect_member++;
}
- // •½‹ÏƒŒƒxƒ‹
- g->average_lv = alv / c;
+
+ if (c)
+ // •½‹ÏƒŒƒxƒ‹
+ g->average_lv = alv / c;
return 0;
}
@@ -1134,7 +1154,7 @@ int guild_break_sub(void *key, void *data, va_list ap) {
int mapif_parse_BreakGuild(int fd, int guild_id) {
struct guild *g;
- g = numdb_search(guild_db, guild_id);
+ g = (struct guild *) numdb_search(guild_db, guild_id);
if(g == NULL)
return 0;
@@ -1145,14 +1165,14 @@ int mapif_parse_BreakGuild(int fd, int guild_id) {
if(log_inter)
inter_log("guild %s (id=%d) broken" RETCODE, g->name, guild_id);
- free(g);
+ aFree(g);
return 0;
}
// ƒMƒ‹ƒhƒƒbƒZ[ƒW‘—M
int mapif_parse_GuildMessage(int fd, int guild_id, int account_id, char *mes, int len) {
- return mapif_guild_message(guild_id, account_id, mes, len);
+ return mapif_guild_message(guild_id, account_id, mes, len, fd);
}
// ƒMƒ‹ƒhŠî–{ƒf[ƒ^•ÏX—v‹
@@ -1160,7 +1180,7 @@ int mapif_parse_GuildBasicInfoChange(int fd, int guild_id, int type, const char
struct guild *g;
short dw = *((short *)data);
- g = numdb_search(guild_db, guild_id);
+ g = (struct guild *) numdb_search(guild_db, guild_id);
if (g == NULL)
return 0;
@@ -1187,7 +1207,7 @@ int mapif_parse_GuildMemberInfoChange(int fd, int guild_id, int account_id, int
int i;
struct guild *g;
- g = numdb_search(guild_db, guild_id);
+ g = (struct guild *) numdb_search(guild_db, guild_id);
if(g == NULL)
return 0;
@@ -1222,7 +1242,7 @@ int mapif_parse_GuildMemberInfoChange(int fd, int guild_id, int account_id, int
// ƒMƒ‹ƒh–ðE–¼•ÏX—v‹
int mapif_parse_GuildPosition(int fd, int guild_id, int idx, struct guild_position *p) {
- struct guild *g = numdb_search(guild_db, guild_id);
+ struct guild *g = (struct guild *) numdb_search(guild_db, guild_id);
if (g == NULL || idx < 0 || idx >= MAX_GUILDPOSITION) {
return 0;
@@ -1236,7 +1256,7 @@ int mapif_parse_GuildPosition(int fd, int guild_id, int idx, struct guild_positi
// ƒMƒ‹ƒhƒXƒLƒ‹ƒAƒbƒv—v‹
int mapif_parse_GuildSkillUp(int fd, int guild_id, int skill_num, int account_id) {
- struct guild *g = numdb_search(guild_db, guild_id);
+ struct guild *g = (struct guild *) numdb_search(guild_db, guild_id);
int idx = skill_num - GD_SKILLBASE;
if (g == NULL || idx < 0 || idx >= MAX_GUILDSKILL)
@@ -1259,8 +1279,8 @@ int mapif_parse_GuildAlliance(int fd, int guild_id1, int guild_id2, int account_
struct guild *g[2];
int j, i;
- g[0] = numdb_search(guild_db, guild_id1);
- g[1] = numdb_search(guild_db, guild_id2);
+ g[0] = (struct guild *) numdb_search(guild_db, guild_id1);
+ g[1] = (struct guild *) numdb_search(guild_db, guild_id2);
if (g[0] == NULL || g[1] == NULL)
return 0;
@@ -1292,7 +1312,7 @@ int mapif_parse_GuildAlliance(int fd, int guild_id1, int guild_id2, int account_
int mapif_parse_GuildNotice(int fd, int guild_id, const char *mes1, const char *mes2) {
struct guild *g;
- g = numdb_search(guild_db, guild_id);
+ g = (struct guild *) numdb_search(guild_db, guild_id);
if (g == NULL)
return 0;
memcpy(g->mes1, mes1, 60);
@@ -1305,7 +1325,7 @@ int mapif_parse_GuildNotice(int fd, int guild_id, const char *mes1, const char *
int mapif_parse_GuildEmblem(int fd, int len, int guild_id, int dummy, const char *data) {
struct guild *g;
- g = numdb_search(guild_db, guild_id);
+ g = (struct guild *) numdb_search(guild_db, guild_id);
if (g == NULL)
return 0;
memcpy(g->emblem_data, data, len);
@@ -1316,7 +1336,7 @@ int mapif_parse_GuildEmblem(int fd, int len, int guild_id, int dummy, const char
}
int mapif_parse_GuildCastleDataLoad(int fd, int castle_id, int index) {
- struct guild_castle *gc = numdb_search(castle_db, castle_id);
+ struct guild_castle *gc = (struct guild_castle *) numdb_search(castle_db, castle_id);
if (gc == NULL) {
return mapif_guild_castle_dataload(castle_id, 0, 0);
@@ -1357,7 +1377,7 @@ int mapif_parse_GuildCastleDataLoad(int fd, int castle_id, int index) {
}
int mapif_parse_GuildCastleDataSave(int fd, int castle_id, int index, int value) {
- struct guild_castle *gc=numdb_search(castle_db, castle_id);
+ struct guild_castle *gc= (struct guild_castle *) numdb_search(castle_db, castle_id);
if (gc == NULL) {
return mapif_guild_castle_datasave(castle_id, index, value);
@@ -1366,10 +1386,10 @@ int mapif_parse_GuildCastleDataSave(int fd, int castle_id, int index, int value)
case 1:
if (gc->guild_id != value) {
int gid = (value) ? value : gc->guild_id;
- struct guild *g = numdb_search(guild_db, gid);
+ struct guild *g = (struct guild *) numdb_search(guild_db, gid);
if(log_inter)
inter_log("guild %s (id=%d) %s castle id=%d" RETCODE,
- (g) ? g->name : "??", gid, (value) ? "occupy" : "abandon", index);
+ (g) ? g->name : "??", gid, (value) ? "occupy" : "abandon", castle_id);
}
gc->guild_id = value;
break;
@@ -1417,21 +1437,21 @@ int mapif_parse_GuildCheck(int fd, int guild_id, int account_id, int char_id) {
// EƒGƒ‰[‚È‚ç0(false)A‚»‚¤‚łȂ¢‚È‚ç1(true)‚ð‚©‚¦‚³‚È‚¯‚ê‚΂Ȃç‚È‚¢
int inter_guild_parse_frommap(int fd) {
switch(RFIFOW(fd,0)) {
- case 0x3030: mapif_parse_CreateGuild(fd, RFIFOL(fd,4), RFIFOP(fd,8), (struct guild_member *)RFIFOP(fd,32)); break;
+ case 0x3030: mapif_parse_CreateGuild(fd, RFIFOL(fd,4), (char*)RFIFOP(fd,8), (struct guild_member *)RFIFOP(fd,32)); break;
case 0x3031: mapif_parse_GuildInfo(fd, RFIFOL(fd,2)); break;
case 0x3032: mapif_parse_GuildAddMember(fd, RFIFOL(fd,4), (struct guild_member *)RFIFOP(fd,8)); break;
- case 0x3034: mapif_parse_GuildLeave(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOB(fd,14), RFIFOP(fd,15)); break;
+ case 0x3034: mapif_parse_GuildLeave(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOB(fd,14), (const char*)RFIFOP(fd,15)); break;
case 0x3035: mapif_parse_GuildChangeMemberInfoShort(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOB(fd,14), RFIFOW(fd,15), RFIFOW(fd,17)); break;
case 0x3036: mapif_parse_BreakGuild(fd, RFIFOL(fd,2)); break;
- case 0x3037: mapif_parse_GuildMessage(fd, RFIFOL(fd,4), RFIFOL(fd,8), RFIFOP(fd,12), RFIFOW(fd,2)-12); break;
+ case 0x3037: mapif_parse_GuildMessage(fd, RFIFOL(fd,4), RFIFOL(fd,8), (char*)RFIFOP(fd,12), RFIFOW(fd,2)-12); break;
case 0x3038: mapif_parse_GuildCheck(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break;
- case 0x3039: mapif_parse_GuildBasicInfoChange(fd, RFIFOL(fd,4), RFIFOW(fd,8), RFIFOP(fd,10), RFIFOW(fd,2)-10); break;
- case 0x303A: mapif_parse_GuildMemberInfoChange(fd, RFIFOL(fd,4), RFIFOL(fd,8), RFIFOL(fd,12), RFIFOW(fd,16), RFIFOP(fd,18), RFIFOW(fd,2)-18); break;
+ case 0x3039: mapif_parse_GuildBasicInfoChange(fd, RFIFOL(fd,4), RFIFOW(fd,8), (const char*)RFIFOP(fd,10), RFIFOW(fd,2)-10); break;
+ case 0x303A: mapif_parse_GuildMemberInfoChange(fd, RFIFOL(fd,4), RFIFOL(fd,8), RFIFOL(fd,12), RFIFOW(fd,16), (const char*)RFIFOP(fd,18), RFIFOW(fd,2)-18); break;
case 0x303B: mapif_parse_GuildPosition(fd, RFIFOL(fd,4), RFIFOL(fd,8), (struct guild_position *)RFIFOP(fd,12)); break;
case 0x303C: mapif_parse_GuildSkillUp(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break;
case 0x303D: mapif_parse_GuildAlliance(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOB(fd,18)); break;
- case 0x303E: mapif_parse_GuildNotice(fd, RFIFOL(fd,2), RFIFOP(fd,6), RFIFOP(fd,66)); break;
- case 0x303F: mapif_parse_GuildEmblem(fd, RFIFOW(fd,2)-12, RFIFOL(fd,4), RFIFOL(fd,8), RFIFOP(fd,12)); break;
+ case 0x303E: mapif_parse_GuildNotice(fd, RFIFOL(fd,2), (const char*)RFIFOP(fd,6), (const char*)RFIFOP(fd,66)); break;
+ case 0x303F: mapif_parse_GuildEmblem(fd, RFIFOW(fd,2)-12, RFIFOL(fd,4), RFIFOL(fd,8), (const char*)RFIFOP(fd,12)); break;
case 0x3040: mapif_parse_GuildCastleDataLoad(fd, RFIFOW(fd,2), RFIFOB(fd,4)); break;
case 0x3041: mapif_parse_GuildCastleDataSave(fd, RFIFOW(fd,2), RFIFOB(fd,4), RFIFOL(fd,5)); break;
diff --git a/src/char/int_guild.h b/src/char/int_guild.h
index 555f5e123..3eeb1b3db 100644
--- a/src/char/int_guild.h
+++ b/src/char/int_guild.h
@@ -3,6 +3,7 @@
#define _INT_GUILD_H_
int inter_guild_init();
+void inter_guild_final();
int inter_guild_save();
int inter_guild_parse_frommap(int fd);
struct guild *inter_guild_search(int guild_id);
diff --git a/src/char/int_party.c b/src/char/int_party.c
index 0fd58fa14..299a75135 100644
--- a/src/char/int_party.c
+++ b/src/char/int_party.c
@@ -19,7 +19,7 @@ int mapif_party_broken(int party_id, int flag);
int party_check_empty(struct party *p);
int mapif_parse_PartyLeave(int fd, int party_id, int account_id);
-// ƒp[ƒeƒBƒf[ƒ^‚Ì•¶Žš—ñ‚ւ̕ϊ·
+// ƒp?ƒeƒBƒf?ƒ^‚Ì•¶Žš—ñ‚Ö‚Ì?Š·
int inter_party_tostr(char *str, struct party *p) {
int i, len;
@@ -32,7 +32,7 @@ int inter_party_tostr(char *str, struct party *p) {
return 0;
}
-// ƒp[ƒeƒBƒf[ƒ^‚Ì•¶Žš—ñ‚©‚ç‚̕ϊ·
+// ƒp?ƒeƒBƒf?ƒ^‚Ì•¶Žš—ñ‚©‚ç‚Ì?Š·
int inter_party_fromstr(char *str, struct party *p) {
int i, j;
int tmp_int[16];
@@ -74,7 +74,7 @@ int inter_party_fromstr(char *str, struct party *p) {
return 0;
}
-// ƒp[ƒeƒBƒf[ƒ^‚̃[ƒh
+// ƒp?ƒeƒBƒf?ƒ^‚̃?ƒh
int inter_party_init() {
char line[8192];
struct party *p;
@@ -94,7 +94,7 @@ int inter_party_init() {
continue;
}
- p = calloc(sizeof(struct party), 1);
+ p = (struct party*)aCalloc(sizeof(struct party), 1);
if (p == NULL){
printf("int_party: out of memory!\n");
exit(0);
@@ -107,7 +107,7 @@ int inter_party_init() {
party_check_empty(p);
} else {
printf("int_party: broken data [%s] line %d\n", party_txt, c + 1);
- free(p);
+ aFree(p);
}
c++;
}
@@ -117,7 +117,18 @@ int inter_party_init() {
return 0;
}
-// ƒp[ƒeƒB[ƒf[ƒ^‚̃Z[ƒu—p
+int party_db_final (void *k, void *data, va_list ap) {
+ struct party *p = (struct party *) data;
+ if (p) aFree(p);
+ return 0;
+}
+void inter_party_final()
+{
+ numdb_final(party_db, party_db_final);
+ return;
+}
+
+// ƒp?ƒeƒB?ƒf?ƒ^‚̃Z?ƒu—p
int inter_party_save_sub(void *key, void *data, va_list ap) {
char line[8192];
FILE *fp;
@@ -129,7 +140,7 @@ int inter_party_save_sub(void *key, void *data, va_list ap) {
return 0;
}
-// ƒp[ƒeƒB[ƒf[ƒ^‚̃Z[ƒu
+// ƒp?ƒeƒB?ƒf?ƒ^‚̃Z?ƒu
int inter_party_save() {
FILE *fp;
int lock;
@@ -146,7 +157,7 @@ int inter_party_save() {
return 0;
}
-// ƒp[ƒeƒB–¼ŒŸõ—p
+// ƒp?ƒeƒB–¼?õ—p
int search_partyname_sub(void *key,void *data,va_list ap) {
struct party *p = (struct party *)data,**dst;
char *str;
@@ -159,7 +170,7 @@ int search_partyname_sub(void *key,void *data,va_list ap) {
return 0;
}
-// ƒp[ƒeƒB–¼ŒŸõ
+// ƒp?ƒeƒB–¼?õ
struct party* search_partyname(char *str) {
struct party *p = NULL;
numdb_foreach(party_db, search_partyname_sub, str, &p);
@@ -169,7 +180,8 @@ struct party* search_partyname(char *str) {
// EXPŒö•½•ª”z‚Å‚«‚é‚©ƒ`ƒFƒbƒN
int party_check_exp_share(struct party *p) {
- int i;
+ int i, dudes=0;
+ int pl1=0,pl2=0,pl3=0;
int maxlv = 0, minlv = 0x7fffffff;
for(i = 0; i < MAX_PARTY; i++) {
@@ -179,13 +191,26 @@ int party_check_exp_share(struct party *p) {
minlv = lv;
if (maxlv < lv)
maxlv = lv;
+ if( lv >= 70 ) dudes+=1000;
+ dudes++;
}
}
-
- return (maxlv == 0 || maxlv-minlv <= party_share_level);
+ if((dudes/1000 >= 2) && (dudes%1000 == 3) && (!strcmp(p->member[0].map,p->member[1].map)) && (!strcmp(p->member[1].map,p->member[2].map))) {
+ pl1=search_character_index(p->member[0].name);
+ pl2=search_character_index(p->member[1].name);
+ pl3=search_character_index(p->member[2].name);
+ printf("PARTY: group of 3 Id1 %d lv %d name %s Id2 %d lv %d name %s Id3 %d lv %d name %s\n",pl1,p->member[0].lv,p->member[0].name,pl2,p->member[1].lv,p->member[1].name,pl3,p->member[2].lv,p->member[2].name);
+ if (char_married(pl1,pl2) && char_child(pl1,pl3))
+ return 1;
+ if (char_married(pl1,pl3) && char_child(pl1,pl2))
+ return 1;
+ if (char_married(pl2,pl3) && char_child(pl2,pl1))
+ return 1;
+ }
+ return (maxlv==0 || maxlv-minlv<=party_share_level);
}
-// ƒp[ƒeƒB‚ª‹ó‚©‚Ç‚¤‚©ƒ`ƒFƒbƒN
+// ƒp?ƒeƒB‚ª‹ó‚©‚Ç‚¤‚©ƒ`ƒFƒbƒN
int party_check_empty(struct party *p) {
int i;
@@ -199,7 +224,7 @@ int party_check_empty(struct party *p) {
// ’N‚à‚¢‚È‚¢‚̂ʼnðŽU
mapif_party_broken(p->party_id, 0);
numdb_erase(party_db, p->party_id);
- free(p);
+ aFree(p);
return 1;
}
@@ -214,12 +239,12 @@ int party_check_conflict_sub(void *key, void *data, va_list ap) {
account_id=va_arg(ap, int);
nick=va_arg(ap, char *);
- if (p->party_id == party_id) // –{—ˆ‚ÌŠ‘®‚Ȃ̂Ŗâ‘è‚È‚µ
+ if (p->party_id == party_id) // –{?‚ÌŠ?‚Ȃ̂Ŗâ‘è‚È‚µ
return 0;
for(i = 0; i < MAX_PARTY; i++) {
if (p->member[i].account_id == account_id && strcmp(p->member[i].name, nick) == 0) {
- // •ʂ̃p[ƒeƒB‚É‹U‚ÌŠ‘®ƒf[ƒ^‚ª‚ ‚é‚̂ŒE‘Þ
+ // •ʂ̃p?ƒeƒB‚É?‚ÌŠ?ƒf?ƒ^‚ª‚ ‚é‚Ì‚Å?‘Þ
printf("int_party: party conflict! %d %d %d\n", account_id, party_id, p->party_id);
mapif_parse_PartyLeave(-1, p->party_id, account_id);
}
@@ -238,7 +263,7 @@ int party_check_conflict(int party_id, int account_id, char *nick) {
//-------------------------------------------------------------------
// map server‚Ö‚Ì’ÊM
-// ƒp[ƒeƒB쬉”Û
+// ƒp?ƒeƒB쬉”Û
int mapif_party_created(int fd,int account_id, struct party *p) {
WFIFOW(fd,0) = 0x3820;
WFIFOL(fd,2) = account_id;
@@ -257,7 +282,7 @@ int mapif_party_created(int fd,int account_id, struct party *p) {
return 0;
}
-// ƒp[ƒeƒBî•ñŒ©‚‚©‚炸
+// ƒp?ƒeƒBî•ñŒ©‚‚©‚炸
int mapif_party_noinfo(int fd, int party_id) {
WFIFOW(fd,0) = 0x3821;
WFIFOW(fd,2) = 8;
@@ -268,9 +293,9 @@ int mapif_party_noinfo(int fd, int party_id) {
return 0;
}
-// ƒp[ƒeƒBî•ñ‚܂Ƃߑ—‚è
+// ƒp?ƒeƒBî•ñ‚܂Ƃߑ—‚è
int mapif_party_info(int fd, struct party *p) {
- unsigned char buf[4 + sizeof(struct party)];
+ unsigned char buf[2048];
WBUFW(buf,0) = 0x3821;
memcpy(buf + 4, p, sizeof(struct party));
@@ -284,7 +309,7 @@ int mapif_party_info(int fd, struct party *p) {
return 0;
}
-// ƒp[ƒeƒBƒƒ“ƒo’ljÁ‰Â”Û
+// ƒp?ƒeƒBƒƒ“ƒo’ljÁ‰Â”Û
int mapif_party_memberadded(int fd, int party_id, int account_id, int flag) {
WFIFOW(fd,0) = 0x3822;
WFIFOL(fd,2) = party_id;
@@ -295,7 +320,7 @@ int mapif_party_memberadded(int fd, int party_id, int account_id, int flag) {
return 0;
}
-// ƒp[ƒeƒBÝ’è•ÏX’Ê’m
+// ƒp?ƒeƒBÝ’è?X’Ê’m
int mapif_party_optionchanged(int fd,struct party *p, int account_id, int flag) {
unsigned char buf[15];
@@ -314,7 +339,7 @@ int mapif_party_optionchanged(int fd,struct party *p, int account_id, int flag)
return 0;
}
-// ƒp[ƒeƒB’E‘Þ’Ê’m
+// ƒp?ƒeƒB?‘Þ’Ê’m
int mapif_party_leaved(int party_id,int account_id, char *name) {
unsigned char buf[34];
@@ -328,7 +353,7 @@ int mapif_party_leaved(int party_id,int account_id, char *name) {
return 0;
}
-// ƒp[ƒeƒBƒ}ƒbƒvXV’Ê’m
+// ƒp?ƒeƒBƒ}ƒbƒvXV’Ê’m
int mapif_party_membermoved(struct party *p, int idx) {
unsigned char buf[29];
@@ -343,7 +368,7 @@ int mapif_party_membermoved(struct party *p, int idx) {
return 0;
}
-// ƒp[ƒeƒB‰ðŽU’Ê’m
+// ƒp?ƒeƒB‰ðŽU’Ê’m
int mapif_party_broken(int party_id, int flag) {
unsigned char buf[7];
WBUFW(buf,0) = 0x3826;
@@ -355,16 +380,16 @@ int mapif_party_broken(int party_id, int flag) {
return 0;
}
-// ƒp[ƒeƒB“à”­Œ¾
-int mapif_party_message(int party_id, int account_id, char *mes, int len) {
- unsigned char buf[len+12];
+// ƒp?ƒeƒB??Œ¾
+int mapif_party_message(int party_id, int account_id, char *mes, int len, int sfd) {
+ unsigned char buf[2048];
WBUFW(buf,0) = 0x3827;
WBUFW(buf,2) = len + 12;
WBUFL(buf,4) = party_id;
WBUFL(buf,8) = account_id;
memcpy(WBUFP(buf,12), mes, len);
- mapif_sendall(buf,len + 12);
+ mapif_sendallwos(sfd, buf,len + 12);
return 0;
}
@@ -373,8 +398,8 @@ int mapif_party_message(int party_id, int account_id, char *mes, int len) {
// map server‚©‚ç‚Ì’ÊM
-// ƒp[ƒeƒB
-int mapif_parse_CreateParty(int fd, int account_id, char *name, char *nick, char *map, int lv) {
+// ƒp?ƒeƒB
+int mapif_parse_CreateParty(int fd, int account_id, char *name, char *nick, char *map, int lv, int item, int item2) {
struct party *p;
int i;
@@ -391,7 +416,7 @@ int mapif_parse_CreateParty(int fd, int account_id, char *name, char *nick, char
mapif_party_created(fd, account_id, NULL);
return 0;
}
- p = calloc(sizeof(struct party), 1);
+ p = (struct party *) aCalloc(sizeof(struct party), 1);
if (p == NULL) {
printf("int_party: out of memory !\n");
mapif_party_created(fd,account_id,NULL);
@@ -401,7 +426,12 @@ int mapif_parse_CreateParty(int fd, int account_id, char *name, char *nick, char
p->party_id = party_newid++;
memcpy(p->name, name, 24);
p->exp = 0;
- p->item = 0;
+ p->item = item;
+ //<item1>ƒAƒCƒeƒ€?W•û–@B0‚ÅŒÂl•ÊA1‚Ńp?ƒeƒBŒö—L
+ //<item2>ƒAƒCƒeƒ€•ª”z•û–@B0‚ÅŒÂl•ÊA1‚Ńp?ƒeƒB‚ɋϓ™•ª”z
+ //difference between "collection" and "distribution" is...? ^^;
+ p->itemc = 0;
+
p->member[0].account_id = account_id;
memcpy(p->member[0].name, nick, 24);
memcpy(p->member[0].map, map, 16);
@@ -417,11 +447,11 @@ int mapif_parse_CreateParty(int fd, int account_id, char *name, char *nick, char
return 0;
}
-// ƒp[ƒeƒBî•ñ—v‹
+// ƒp?ƒeƒBî•ñ—v‹
int mapif_parse_PartyInfo(int fd, int party_id) {
struct party *p;
- p = numdb_search(party_db, party_id);
+ p = (struct party *) numdb_search(party_db, party_id);
if (p != NULL)
mapif_party_info(fd, p);
else
@@ -430,12 +460,12 @@ int mapif_parse_PartyInfo(int fd, int party_id) {
return 0;
}
-// ƒp[ƒeƒB’ljÁ—v‹
+// ƒp?ƒeƒB’ljÁ—v‹
int mapif_parse_PartyAddMember(int fd, int party_id, int account_id, char *nick, char *map, int lv) {
struct party *p;
int i;
- p = numdb_search(party_db, party_id);
+ p = (struct party *) numdb_search(party_db, party_id);
if (p == NULL) {
mapif_party_memberadded(fd, party_id, account_id, 1);
return 0;
@@ -468,12 +498,12 @@ int mapif_parse_PartyAddMember(int fd, int party_id, int account_id, char *nick,
return 0;
}
-// ƒp[ƒeƒB[Ý’è•ÏX—v‹
+// ƒp?ƒeƒB?Ý’è?X—v‹
int mapif_parse_PartyChangeOption(int fd, int party_id, int account_id, int exp, int item) {
struct party *p;
int flag = 0;
- p = numdb_search(party_db, party_id);
+ p = (struct party *) numdb_search(party_db, party_id);
if (p == NULL)
return 0;
@@ -489,12 +519,12 @@ int mapif_parse_PartyChangeOption(int fd, int party_id, int account_id, int exp,
return 0;
}
-// ƒp[ƒeƒB’E‘Þ—v‹
+// ƒp?ƒeƒB?‘Þ—v‹
int mapif_parse_PartyLeave(int fd, int party_id, int account_id) {
struct party *p;
int i;
- p = numdb_search(party_db, party_id);
+ p = (struct party *) numdb_search(party_db, party_id);
if (p != NULL) {
for(i = 0; i < MAX_PARTY; i++) {
if (p->member[i].account_id == account_id) {
@@ -502,7 +532,7 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id) {
memset(&p->member[i], 0, sizeof(struct party_member));
if (party_check_empty(p) == 0)
- mapif_party_info(-1, p);// ‚Ü‚¾l‚ª‚¢‚é‚̂Ńf[ƒ^‘—M
+ mapif_party_info(-1, p);// ‚Ü‚¾l‚ª‚¢‚é‚̂Ńf?ƒ^‘—M
return 0;
}
}
@@ -511,12 +541,12 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id) {
return 0;
}
-// ƒp[ƒeƒBƒ}ƒbƒvXV—v‹
+// ƒp?ƒeƒBƒ}ƒbƒvXV—v‹
int mapif_parse_PartyChangeMap(int fd, int party_id, int account_id, char *map, int online, int lv) {
struct party *p;
int i;
- p = numdb_search(party_db, party_id);
+ p = (struct party *) numdb_search(party_db, party_id);
if (p == NULL)
return 0;
@@ -542,11 +572,11 @@ int mapif_parse_PartyChangeMap(int fd, int party_id, int account_id, char *map,
return 0;
}
-// ƒp[ƒeƒB‰ðŽU—v‹
+// ƒp?ƒeƒB‰ðŽU—v‹
int mapif_parse_BreakParty(int fd, int party_id) {
struct party *p;
- p = numdb_search(party_db, party_id);
+ p = (struct party *) numdb_search(party_db, party_id);
if (p == NULL)
return 0;
@@ -556,31 +586,31 @@ int mapif_parse_BreakParty(int fd, int party_id) {
return 0;
}
-// ƒp[ƒeƒBƒƒbƒZ[ƒW‘—M
+// ƒp?ƒeƒBƒƒbƒZ?ƒW‘—M
int mapif_parse_PartyMessage(int fd, int party_id, int account_id, char *mes, int len) {
- return mapif_party_message(party_id, account_id, mes, len);
+ return mapif_party_message(party_id, account_id, mes, len, fd);
}
-// ƒp[ƒeƒBƒ`ƒFƒbƒN—v‹
+// ƒp?ƒeƒBƒ`ƒFƒbƒN—v‹
int mapif_parse_PartyCheck(int fd, int party_id, int account_id, char *nick) {
return party_check_conflict(party_id, account_id, nick);
}
// map server ‚©‚ç‚Ì’ÊM
-// E‚PƒpƒPƒbƒg‚̂݉ðÍ‚·‚邱‚Æ
-// EƒpƒPƒbƒg’·ƒf[ƒ^‚Íinter.c‚ɃZƒbƒg‚µ‚Ä‚¨‚­‚±‚Æ
-// EƒpƒPƒbƒg’·ƒ`ƒFƒbƒN‚âARFIFOSKIP‚͌ĂÑo‚µŒ³‚Ås‚í‚ê‚é‚Ì‚Ås‚Á‚Ă͂Ȃç‚È‚¢
-// EƒGƒ‰[‚È‚ç0(false)A‚»‚¤‚łȂ¢‚È‚ç1(true)‚ð‚©‚¦‚³‚È‚¯‚ê‚΂Ȃç‚È‚¢
+// ?‚PƒpƒPƒbƒg‚̂݉ðÍ‚·‚邱‚Æ
+// ?ƒpƒPƒbƒg’·ƒf?ƒ^‚Íinter.c‚ɃZƒbƒg‚µ‚Ä‚¨‚­‚±‚Æ
+// ?ƒpƒPƒbƒg’·ƒ`ƒFƒbƒN‚âARFIFOSKIP‚͌ĂÑo‚µŒ³‚Ås‚í‚ê‚é‚Ì‚Ås‚Á‚Ă͂Ȃç‚È‚¢
+// ?ƒGƒ‰?‚È‚ç0(false)A‚»‚¤‚łȂ¢‚È‚ç1(true)‚ð‚©‚¦‚³‚È‚¯‚ê‚΂Ȃç‚È‚¢
int inter_party_parse_frommap(int fd) {
switch(RFIFOW(fd,0)) {
- case 0x3020: mapif_parse_CreateParty(fd, RFIFOL(fd,2), RFIFOP(fd,6), RFIFOP(fd,30), RFIFOP(fd,54), RFIFOW(fd,70)); break;
+ case 0x3020: mapif_parse_CreateParty(fd, RFIFOL(fd,2), (char*)RFIFOP(fd,6), (char*)RFIFOP(fd,30), (char*)RFIFOP(fd,54), RFIFOW(fd,70), RFIFOB(fd,72), RFIFOB(fd,73)); break;
case 0x3021: mapif_parse_PartyInfo(fd, RFIFOL(fd,2)); break;
- case 0x3022: mapif_parse_PartyAddMember(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOP(fd,10), RFIFOP(fd,34), RFIFOW(fd,50)); break;
+ case 0x3022: mapif_parse_PartyAddMember(fd, RFIFOL(fd,2), RFIFOL(fd,6), (char*)RFIFOP(fd,10), (char*)RFIFOP(fd,34), RFIFOW(fd,50)); break;
case 0x3023: mapif_parse_PartyChangeOption(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOW(fd,10), RFIFOW(fd,12)); break;
case 0x3024: mapif_parse_PartyLeave(fd, RFIFOL(fd,2), RFIFOL(fd,6)); break;
- case 0x3025: mapif_parse_PartyChangeMap(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOP(fd,10), RFIFOB(fd,26), RFIFOW(fd,27)); break;
+ case 0x3025: mapif_parse_PartyChangeMap(fd, RFIFOL(fd,2), RFIFOL(fd,6), (char*)RFIFOP(fd,10), RFIFOB(fd,26), RFIFOW(fd,27)); break;
case 0x3026: mapif_parse_BreakParty(fd, RFIFOL(fd,2)); break;
- case 0x3027: mapif_parse_PartyMessage(fd, RFIFOL(fd,4), RFIFOL(fd,8), RFIFOP(fd,12), RFIFOW(fd,2)-12); break;
- case 0x3028: mapif_parse_PartyCheck(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOP(fd,10)); break;
+ case 0x3027: mapif_parse_PartyMessage(fd, RFIFOL(fd,4), RFIFOL(fd,8), (char*)RFIFOP(fd,12), RFIFOW(fd,2)-12); break;
+ case 0x3028: mapif_parse_PartyCheck(fd, RFIFOL(fd,2), RFIFOL(fd,6), (char*)RFIFOP(fd,10)); break;
default:
return 0;
}
@@ -588,7 +618,7 @@ int inter_party_parse_frommap(int fd) {
return 1;
}
-// ƒT[ƒo[‚©‚ç’E‘Þ—v‹iƒLƒƒƒ‰íœ—pj
+// ƒT?ƒo?‚©‚ç?‘Þ—v‹iƒLƒƒƒ‰íœ—pj
int inter_party_leave(int party_id, int account_id) {
return mapif_parse_PartyLeave(-1, party_id, account_id);
}
diff --git a/src/char/int_party.h b/src/char/int_party.h
index b265b4c2e..e3180f3b7 100644
--- a/src/char/int_party.h
+++ b/src/char/int_party.h
@@ -3,6 +3,7 @@
#define _INT_PARTY_H_
int inter_party_init();
+void inter_party_final();
int inter_party_save();
int inter_party_parse_frommap(int fd);
diff --git a/src/char/int_pet.c b/src/char/int_pet.c
index cff1e434f..ab53d0533 100644
--- a/src/char/int_pet.c
+++ b/src/char/int_pet.c
@@ -30,7 +30,7 @@ int inter_pet_tostr(char *str,struct s_pet *p)
p->intimate = 1000;
len=sprintf(str,"%d,%d,%s\t%d,%d,%d,%d,%d,%d,%d,%d,%d",
- p->pet_id,p->class,p->name,p->account_id,p->char_id,p->level,p->egg_id,
+ p->pet_id,p->class_,p->name,p->account_id,p->char_id,p->level,p->egg_id,
p->equip,p->intimate,p->hungry,p->rename_flag,p->incuvate);
return 0;
@@ -41,18 +41,18 @@ int inter_pet_fromstr(char *str,struct s_pet *p)
int s;
int tmp_int[16];
char tmp_str[256];
-
+
memset(p,0,sizeof(struct s_pet));
-
+
// printf("sscanf pet main info\n");
s=sscanf(str,"%d,%d,%[^\t]\t%d,%d,%d,%d,%d,%d,%d,%d,%d",&tmp_int[0],&tmp_int[1],tmp_str,&tmp_int[2],
&tmp_int[3],&tmp_int[4],&tmp_int[5],&tmp_int[6],&tmp_int[7],&tmp_int[8],&tmp_int[9],&tmp_int[10]);
if(s!=12)
return 1;
-
+
p->pet_id = tmp_int[0];
- p->class = tmp_int[1];
+ p->class_ = tmp_int[1];
memcpy(p->name,tmp_str,24);
p->account_id = tmp_int[2];
p->char_id = tmp_int[3];
@@ -88,7 +88,7 @@ int inter_pet_init()
if( (fp=fopen(pet_txt,"r"))==NULL )
return 1;
while(fgets(line,sizeof(line),fp)){
- p=calloc(sizeof(struct s_pet), 1);
+ p = (struct s_pet*)aCalloc(sizeof(struct s_pet), 1);
if(p==NULL){
printf("int_pet: out of memory!\n");
exit(0);
@@ -100,7 +100,7 @@ int inter_pet_init()
numdb_insert(pet_db,p->pet_id,p);
}else{
printf("int_pet: broken data [%s] line %d\n",pet_txt,c);
- free(p);
+ aFree(p);
}
c++;
}
@@ -109,6 +109,17 @@ int inter_pet_init()
return 0;
}
+int pet_db_final (void *k, void *data, va_list ap) {
+ struct s_pet *p = (struct s_pet *) data;
+ if (p) aFree(p);
+ return 0;
+}
+void inter_pet_final()
+{
+ numdb_final(pet_db, pet_db_final);
+ return;
+}
+
int inter_pet_save_sub(void *key,void *data,va_list ap)
{
char line[8192];
@@ -136,7 +147,7 @@ int inter_pet_save()
int inter_pet_delete(int pet_id)
{
struct s_pet *p;
- p = numdb_search(pet_db,pet_id);
+ p = (struct s_pet *) numdb_search(pet_db,pet_id);
if( p == NULL)
return 1;
else {
@@ -210,7 +221,7 @@ int mapif_create_pet(int fd,int account_id,int char_id,short pet_class,short pet
short pet_equip,short intimate,short hungry,char rename_flag,char incuvate,char *pet_name)
{
struct s_pet *p;
- p=malloc(sizeof(struct s_pet));
+ p= (struct s_pet *) aMalloc(sizeof(struct s_pet));
if(p==NULL){
printf("int_pet: out of memory !\n");
mapif_pet_created(fd,account_id,NULL);
@@ -225,7 +236,7 @@ int mapif_create_pet(int fd,int account_id,int char_id,short pet_class,short pet
p->account_id = account_id;
p->char_id = char_id;
}
- p->class = pet_class;
+ p->class_ = pet_class;
p->level = pet_lv;
p->egg_id = pet_egg_id;
p->equip = pet_equip;
@@ -242,18 +253,18 @@ int mapif_create_pet(int fd,int account_id,int char_id,short pet_class,short pet
p->intimate = 0;
else if(p->intimate > 1000)
p->intimate = 1000;
-
+
numdb_insert(pet_db,p->pet_id,p);
-
+
mapif_pet_created(fd,account_id,p);
-
+
return 0;
}
int mapif_load_pet(int fd,int account_id,int char_id,int pet_id)
{
struct s_pet *p;
- p=numdb_search(pet_db,pet_id);
+ p=(struct s_pet *)numdb_search(pet_db,pet_id);
if(p!=NULL) {
if(p->incuvate == 1) {
p->account_id = p->char_id = 0;
@@ -280,9 +291,9 @@ int mapif_save_pet(int fd,int account_id,struct s_pet *data)
}
else{
pet_id = data->pet_id;
- p=numdb_search(pet_db,pet_id);
+ p=(struct s_pet *)numdb_search(pet_db,pet_id);
if(p == NULL) {
- p=malloc(sizeof(struct s_pet));
+ p=(struct s_pet *)aMalloc(sizeof(struct s_pet));
if(p==NULL){
printf("int_pet: out of memory !\n");
mapif_save_pet_ack(fd,account_id,1);
@@ -292,7 +303,7 @@ int mapif_save_pet(int fd,int account_id,struct s_pet *data)
p->pet_id = data->pet_id;
if(p->pet_id == 0)
data->pet_id = p->pet_id = pet_newid++;
- numdb_insert(pet_db,p->pet_id,p);
+ numdb_insert(pet_db,p->pet_id,p);
}
if(data->hungry < 0)
data->hungry = 0;
@@ -322,7 +333,7 @@ int mapif_delete_pet(int fd,int pet_id)
int mapif_parse_CreatePet(int fd)
{
mapif_create_pet(fd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOW(fd,10),RFIFOW(fd,12),RFIFOW(fd,14),RFIFOW(fd,16),RFIFOL(fd,18),
- RFIFOL(fd,20),RFIFOB(fd,22),RFIFOB(fd,23),RFIFOP(fd,24));
+ RFIFOL(fd,20),RFIFOB(fd,22),RFIFOB(fd,23),(char*)RFIFOP(fd,24));
return 0;
}
diff --git a/src/char/int_pet.h b/src/char/int_pet.h
index 993f913ab..3a48ada3b 100644
--- a/src/char/int_pet.h
+++ b/src/char/int_pet.h
@@ -3,6 +3,7 @@
#define _INT_PET_H_
int inter_pet_init();
+void inter_pet_final();
int inter_pet_save();
int inter_pet_delete(int pet_id);
diff --git a/src/char/int_storage.c b/src/char/int_storage.c
index 7a4022a55..eaf9e001a 100644
--- a/src/char/int_storage.c
+++ b/src/char/int_storage.c
@@ -28,11 +28,11 @@ int storage_tostr(char *str,struct storage *p)
str_p += sprintf(str_p,"%d,%d\t",p->account_id,p->storage_amount);
for(i=0;i<MAX_STORAGE;i++)
- if( (p->storage[i].nameid) && (p->storage[i].amount) ){
+ if( (p->storage_[i].nameid) && (p->storage_[i].amount) ){
str_p += sprintf(str_p,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d ",
- p->storage[i].id,p->storage[i].nameid,p->storage[i].amount,p->storage[i].equip,
- p->storage[i].identify,p->storage[i].refine,p->storage[i].attribute,
- p->storage[i].card[0],p->storage[i].card[1],p->storage[i].card[2],p->storage[i].card[3]);
+ p->storage_[i].id,p->storage_[i].nameid,p->storage_[i].amount,p->storage_[i].equip,
+ p->storage_[i].identify,p->storage_[i].refine,p->storage_[i].attribute,
+ p->storage_[i].card[0],p->storage_[i].card[1],p->storage_[i].card[2],p->storage_[i].card[3]);
f++;
}
@@ -56,49 +56,49 @@ int storage_fromstr(char *str,struct storage *p)
if(set!=2)
return 1;
if(str[next]=='\n' || str[next]=='\r')
- return 0;
+ return 0;
next++;
for(i=0;str[next] && str[next]!='\t';i++){
if(sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
&tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
&tmp_int[4], &tmp_int[5], &tmp_int[6],
&tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10], &tmp_int[10], &len) == 12) {
- p->storage[i].id = tmp_int[0];
- p->storage[i].nameid = tmp_int[1];
- p->storage[i].amount = tmp_int[2];
- p->storage[i].equip = tmp_int[3];
- p->storage[i].identify = tmp_int[4];
- p->storage[i].refine = tmp_int[5];
- p->storage[i].attribute = tmp_int[6];
- p->storage[i].card[0] = tmp_int[7];
- p->storage[i].card[1] = tmp_int[8];
- p->storage[i].card[2] = tmp_int[9];
- p->storage[i].card[3] = tmp_int[10];
+ p->storage_[i].id = tmp_int[0];
+ p->storage_[i].nameid = tmp_int[1];
+ p->storage_[i].amount = tmp_int[2];
+ p->storage_[i].equip = tmp_int[3];
+ p->storage_[i].identify = tmp_int[4];
+ p->storage_[i].refine = tmp_int[5];
+ p->storage_[i].attribute = tmp_int[6];
+ p->storage_[i].card[0] = tmp_int[7];
+ p->storage_[i].card[1] = tmp_int[8];
+ p->storage_[i].card[2] = tmp_int[9];
+ p->storage_[i].card[3] = tmp_int[10];
next += len;
if (str[next] == ' ')
- next++;
+ next++;
}
else if(sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
&tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
&tmp_int[4], &tmp_int[5], &tmp_int[6],
&tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10], &len) == 11) {
- p->storage[i].id = tmp_int[0];
- p->storage[i].nameid = tmp_int[1];
- p->storage[i].amount = tmp_int[2];
- p->storage[i].equip = tmp_int[3];
- p->storage[i].identify = tmp_int[4];
- p->storage[i].refine = tmp_int[5];
- p->storage[i].attribute = tmp_int[6];
- p->storage[i].card[0] = tmp_int[7];
- p->storage[i].card[1] = tmp_int[8];
- p->storage[i].card[2] = tmp_int[9];
- p->storage[i].card[3] = tmp_int[10];
+ p->storage_[i].id = tmp_int[0];
+ p->storage_[i].nameid = tmp_int[1];
+ p->storage_[i].amount = tmp_int[2];
+ p->storage_[i].equip = tmp_int[3];
+ p->storage_[i].identify = tmp_int[4];
+ p->storage_[i].refine = tmp_int[5];
+ p->storage_[i].attribute = tmp_int[6];
+ p->storage_[i].card[0] = tmp_int[7];
+ p->storage_[i].card[1] = tmp_int[8];
+ p->storage_[i].card[2] = tmp_int[9];
+ p->storage_[i].card[3] = tmp_int[10];
next += len;
if (str[next] == ' ')
- next++;
+ next++;
}
-
+
else return 1;
}
return 0;
@@ -111,11 +111,11 @@ int guild_storage_tostr(char *str,struct guild_storage *p)
str_p+=sprintf(str,"%d,%d\t",p->guild_id,p->storage_amount);
for(i=0;i<MAX_GUILD_STORAGE;i++)
- if( (p->storage[i].nameid) && (p->storage[i].amount) ){
+ if( (p->storage_[i].nameid) && (p->storage_[i].amount) ){
str_p += sprintf(str_p,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d ",
- p->storage[i].id,p->storage[i].nameid,p->storage[i].amount,p->storage[i].equip,
- p->storage[i].identify,p->storage[i].refine,p->storage[i].attribute,
- p->storage[i].card[0],p->storage[i].card[1],p->storage[i].card[2],p->storage[i].card[3]);
+ p->storage_[i].id,p->storage_[i].nameid,p->storage_[i].amount,p->storage_[i].equip,
+ p->storage_[i].identify,p->storage_[i].refine,p->storage_[i].attribute,
+ p->storage_[i].card[0],p->storage_[i].card[1],p->storage_[i].card[2],p->storage_[i].card[3]);
f++;
}
@@ -138,49 +138,49 @@ int guild_storage_fromstr(char *str,struct guild_storage *p)
if(set!=2)
return 1;
if(str[next]=='\n' || str[next]=='\r')
- return 0;
+ return 0;
next++;
for(i=0;str[next] && str[next]!='\t';i++){
if(sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
&tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
&tmp_int[4], &tmp_int[5], &tmp_int[6],
&tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10], &tmp_int[10], &len) == 12) {
- p->storage[i].id = tmp_int[0];
- p->storage[i].nameid = tmp_int[1];
- p->storage[i].amount = tmp_int[2];
- p->storage[i].equip = tmp_int[3];
- p->storage[i].identify = tmp_int[4];
- p->storage[i].refine = tmp_int[5];
- p->storage[i].attribute = tmp_int[6];
- p->storage[i].card[0] = tmp_int[7];
- p->storage[i].card[1] = tmp_int[8];
- p->storage[i].card[2] = tmp_int[9];
- p->storage[i].card[3] = tmp_int[10];
+ p->storage_[i].id = tmp_int[0];
+ p->storage_[i].nameid = tmp_int[1];
+ p->storage_[i].amount = tmp_int[2];
+ p->storage_[i].equip = tmp_int[3];
+ p->storage_[i].identify = tmp_int[4];
+ p->storage_[i].refine = tmp_int[5];
+ p->storage_[i].attribute = tmp_int[6];
+ p->storage_[i].card[0] = tmp_int[7];
+ p->storage_[i].card[1] = tmp_int[8];
+ p->storage_[i].card[2] = tmp_int[9];
+ p->storage_[i].card[3] = tmp_int[10];
next += len;
if (str[next] == ' ')
- next++;
+ next++;
}
else if(sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
&tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
&tmp_int[4], &tmp_int[5], &tmp_int[6],
&tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10], &len) == 11) {
- p->storage[i].id = tmp_int[0];
- p->storage[i].nameid = tmp_int[1];
- p->storage[i].amount = tmp_int[2];
- p->storage[i].equip = tmp_int[3];
- p->storage[i].identify = tmp_int[4];
- p->storage[i].refine = tmp_int[5];
- p->storage[i].attribute = tmp_int[6];
- p->storage[i].card[0] = tmp_int[7];
- p->storage[i].card[1] = tmp_int[8];
- p->storage[i].card[2] = tmp_int[9];
- p->storage[i].card[3] = tmp_int[10];
+ p->storage_[i].id = tmp_int[0];
+ p->storage_[i].nameid = tmp_int[1];
+ p->storage_[i].amount = tmp_int[2];
+ p->storage_[i].equip = tmp_int[3];
+ p->storage_[i].identify = tmp_int[4];
+ p->storage_[i].refine = tmp_int[5];
+ p->storage_[i].attribute = tmp_int[6];
+ p->storage_[i].card[0] = tmp_int[7];
+ p->storage_[i].card[1] = tmp_int[8];
+ p->storage_[i].card[2] = tmp_int[9];
+ p->storage_[i].card[3] = tmp_int[10];
next += len;
if (str[next] == ' ')
- next++;
+ next++;
}
-
+
else return 1;
}
return 0;
@@ -190,9 +190,9 @@ int guild_storage_fromstr(char *str,struct guild_storage *p)
struct storage *account2storage(int account_id)
{
struct storage *s;
- s=numdb_search(storage_db,account_id);
+ s= (struct storage *) numdb_search(storage_db,account_id);
if(s == NULL) {
- s = calloc(sizeof(struct storage), 1);
+ s = (struct storage *) aCalloc(sizeof(struct storage), 1);
if(s==NULL){
printf("int_storage: out of memory!\n");
exit(0);
@@ -208,9 +208,9 @@ struct guild_storage *guild2storage(int guild_id)
{
struct guild_storage *gs = NULL;
if(inter_guild_search(guild_id) != NULL) {
- gs=numdb_search(guild_storage_db,guild_id);
+ gs= (struct guild_storage *) numdb_search(guild_storage_db,guild_id);
if(gs == NULL) {
- gs = calloc(sizeof(struct guild_storage), 1);
+ gs = (struct guild_storage *) aCalloc(sizeof(struct guild_storage), 1);
if(gs==NULL){
printf("int_storage: out of memory!\n");
exit(0);
@@ -242,7 +242,7 @@ int inter_storage_init()
}
while(fgets(line,65535,fp)){
sscanf(line,"%d",&tmp_int);
- s=calloc(sizeof(struct storage), 1);
+ s = (struct storage*)aCalloc(sizeof(struct storage), 1);
if(s==NULL){
printf("int_storage: out of memory!\n");
exit(0);
@@ -254,7 +254,7 @@ int inter_storage_init()
}
else{
printf("int_storage: broken data [%s] line %d\n",storage_txt,c);
- free(s);
+ aFree(s);
}
c++;
}
@@ -270,7 +270,7 @@ int inter_storage_init()
}
while(fgets(line,65535,fp)){
sscanf(line,"%d",&tmp_int);
- gs=calloc(sizeof(struct guild_storage), 1);
+ gs = (struct guild_storage*)aCalloc(sizeof(struct guild_storage), 1);
if(gs==NULL){
printf("int_storage: out of memory!\n");
exit(0);
@@ -282,7 +282,7 @@ int inter_storage_init()
}
else{
printf("int_storage: broken data [%s] line %d\n",guild_storage_txt,c);
- free(gs);
+ aFree(gs);
}
c++;
}
@@ -291,6 +291,22 @@ int inter_storage_init()
return 0;
}
+int storage_db_final (void *k, void *data, va_list ap) {
+ struct storage *p = (struct storage *) data;
+ if (p) aFree(p);
+ return 0;
+}
+int guild_storage_db_final (void *k, void *data, va_list ap) {
+ struct guild_storage *p = (struct guild_storage *) data;
+ if (p) aFree(p);
+ return 0;
+}
+void inter_storage_final() {
+ numdb_final(storage_db, storage_db_final);
+ numdb_final(guild_storage_db, guild_storage_db_final);
+ return;
+}
+
int inter_storage_save_sub(void *key,void *data,va_list ap)
{
char line[65536];
@@ -348,15 +364,15 @@ int inter_guild_storage_save()
// ‘qŒÉƒf[ƒ^íœ
int inter_storage_delete(int account_id)
{
- struct storage *s = numdb_search(storage_db,account_id);
+ struct storage *s = (struct storage *) numdb_search(storage_db,account_id);
if(s) {
int i;
for(i=0;i<s->storage_amount;i++){
- if(s->storage[i].card[0] == (short)0xff00)
- inter_pet_delete(*((long *)(&s->storage[i].card[2])));
+ if(s->storage_[i].card[0] == (short)0xff00)
+ inter_pet_delete(*((long *)(&s->storage_[i].card[2])));
}
numdb_erase(storage_db,account_id);
- free(s);
+ aFree(s);
}
return 0;
}
@@ -364,15 +380,15 @@ int inter_storage_delete(int account_id)
// ƒMƒ‹ƒh‘qŒÉƒf[ƒ^íœ
int inter_guild_storage_delete(int guild_id)
{
- struct guild_storage *gs = numdb_search(guild_storage_db,guild_id);
+ struct guild_storage *gs = (struct guild_storage *) numdb_search(guild_storage_db,guild_id);
if(gs) {
int i;
for(i=0;i<gs->storage_amount;i++){
- if(gs->storage[i].card[0] == (short)0xff00)
- inter_pet_delete(*((long *)(&gs->storage[i].card[2])));
+ if(gs->storage_[i].card[0] == (short)0xff00)
+ inter_pet_delete(*((long *)(&gs->storage_[i].card[2])));
}
numdb_erase(guild_storage_db,guild_id);
- free(gs);
+ aFree(gs);
}
return 0;
}
diff --git a/src/char/int_storage.h b/src/char/int_storage.h
index d918f5fe3..f228be53d 100644
--- a/src/char/int_storage.h
+++ b/src/char/int_storage.h
@@ -3,6 +3,7 @@
#define _INT_STORAGE_H_
int inter_storage_init();
+void inter_storage_final();
int inter_storage_save();
int inter_guild_storage_save();
int inter_storage_delete(int account_id);
diff --git a/src/char/inter.c b/src/char/inter.c
index bf7bdcccf..0dca38559 100644
--- a/src/char/inter.c
+++ b/src/char/inter.c
@@ -47,7 +47,7 @@ int inter_send_packet_length[] = {
int inter_recv_packet_length[] = {
-1,-1, 7,-1, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0,
- 72, 6,52,14, 10,29, 6,-1, 34, 0, 0, 0, 0, 0, 0, 0,
+ 74, 6,52,14, 10,29, 6,-1, 34, 0, 0, 0, 0, 0, 0, 0,
-1, 6,-1, 0, 55,19, 6,-1, 14,-1,-1,-1, 14,19,186,-1,
5, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -114,7 +114,7 @@ int inter_accreg_init() {
while(fgets(line, sizeof(line)-1, fp)){
line[sizeof(line)-1] = '\0';
- reg = calloc(sizeof(struct accreg), 1);
+ reg = (struct accreg*)aCalloc(sizeof(struct accreg), 1);
if (reg == NULL) {
printf("inter: accreg: out of memory!\n");
exit(0);
@@ -123,7 +123,7 @@ int inter_accreg_init() {
numdb_insert(accreg_db, reg->account_id, reg);
} else {
printf("inter: accreg: broken data [%s] line %d\n", accreg_txt, c);
- free(reg);
+ aFree(reg);
}
c++;
}
@@ -261,6 +261,29 @@ int inter_init(const char *file) {
return 0;
}
+// finalize
+int accreg_db_final (void *k, void *data, va_list ap) {
+ struct accreg *p = (struct accreg *) data;
+ if (p) aFree(p);
+ return 0;
+}
+int wis_db_final (void *k, void *data, va_list ap) {
+ struct WisData *p = (struct WisData *) data;
+ if (p) aFree(p);
+ return 0;
+}
+void inter_final() {
+ numdb_final(accreg_db, accreg_db_final);
+ numdb_final(wis_db, wis_db_final);
+
+ inter_party_final();
+ inter_guild_final();
+ inter_storage_final();
+ inter_pet_final();
+
+ return;
+}
+
// ƒ}ƒbƒvƒT[ƒo[Ú‘±
int inter_mapif_init(int fd) {
inter_guild_mapif_init(fd);
@@ -272,13 +295,13 @@ int inter_mapif_init(int fd) {
// sended packets to map-server
// GMƒƒbƒZ[ƒW‘—M
-int mapif_GMmessage(unsigned char *mes, int len) {
- unsigned char buf[len];
+int mapif_GMmessage(unsigned char *mes, int len, int sfd) {
+ unsigned char buf[2048];
WBUFW(buf,0) = 0x3800;
WBUFW(buf,2) = len;
memcpy(WBUFP(buf,4), mes, len - 4);
- mapif_sendall(buf, len);
+ mapif_sendallwos(sfd, buf, len);
// printf("inter server: GM:%d %s\n", len, mes);
return 0;
@@ -286,7 +309,7 @@ int mapif_GMmessage(unsigned char *mes, int len) {
// Wisp/page transmission to all map-server
int mapif_wis_message(struct WisData *wd) {
- unsigned char buf[56 + wd->len];
+ unsigned char buf[2048];
WBUFW(buf, 0) = 0x3801;
WBUFW(buf, 2) = 56 + wd->len;
@@ -314,7 +337,7 @@ int mapif_wis_end(struct WisData *wd, int flag) {
// ƒAƒJƒEƒ“ƒg•Ï”‘—M
int mapif_account_reg(int fd, unsigned char *src) {
- unsigned char buf[WBUFW(src,2)];
+ unsigned char buf[2048];
memcpy(WBUFP(buf,0),src,WBUFW(src,2));
WBUFW(buf, 0) = 0x3804;
@@ -325,7 +348,7 @@ int mapif_account_reg(int fd, unsigned char *src) {
// ƒAƒJƒEƒ“ƒg•Ï”—v‹•ÔM
int mapif_account_reg_reply(int fd,int account_id) {
- struct accreg *reg = numdb_search(accreg_db,account_id);
+ struct accreg *reg = (struct accreg*)numdb_search(accreg_db,account_id);
WFIFOW(fd,0) = 0x3804;
WFIFOL(fd,4) = account_id;
@@ -366,12 +389,12 @@ int check_ttl_wisdata() {
wis_delnum = 0;
numdb_foreach(wis_db, check_ttl_wisdata_sub, tick);
for(i = 0; i < wis_delnum; i++) {
- struct WisData *wd = numdb_search(wis_db, wis_dellist[i]);
+ struct WisData *wd = (struct WisData*)numdb_search(wis_db, wis_dellist[i]);
printf("inter: wis data id=%d time out : from %s to %s\n", wd->id, wd->src, wd->dst);
// removed. not send information after a timeout. Just no answer for the player
//mapif_wis_end(wd, 1); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
numdb_erase(wis_db, wd->id);
- free(wd);
+ aFree(wd);
}
} while(wis_delnum >= WISDELLIST_MAX);
@@ -383,7 +406,7 @@ int check_ttl_wisdata() {
// GMƒƒbƒZ[ƒW‘—M
int mapif_parse_GMmessage(int fd) {
- mapif_GMmessage(RFIFOP(fd,4), RFIFOW(fd,2));
+ mapif_GMmessage(RFIFOP(fd,4), RFIFOW(fd,2), fd);
return 0;
}
@@ -403,7 +426,7 @@ int mapif_parse_WisRequest(int fd) {
}
// search if character exists before to ask all map-servers
- if ((index = search_character_index(RFIFOP(fd,28))) == -1) {
+ if ((index = search_character_index((char*)RFIFOP(fd,28))) == -1) {
unsigned char buf[27];
WBUFW(buf, 0) = 0x3802;
memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), 24);
@@ -413,9 +436,9 @@ int mapif_parse_WisRequest(int fd) {
} else {
// to be sure of the correct name, rewrite it
memset(RFIFOP(fd,28), 0, 24);
- strncpy(RFIFOP(fd,28), search_character_name(index), 24);
+ strncpy((char*)RFIFOP(fd,28), search_character_name(index), 24);
// if source is destination, don't ask other servers.
- if (strcmp(RFIFOP(fd,4),RFIFOP(fd,28)) == 0) {
+ if (strcmp((char*)RFIFOP(fd,4),(char*)RFIFOP(fd,28)) == 0) {
unsigned char buf[27];
WBUFW(buf, 0) = 0x3802;
memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), 24);
@@ -423,7 +446,7 @@ int mapif_parse_WisRequest(int fd) {
mapif_send(fd, buf, 27);
} else {
- wd = (struct WisData *)calloc(sizeof(struct WisData), 1);
+ wd = (struct WisData *)aCalloc(sizeof(struct WisData), 1);
if (wd == NULL){
printf("inter: WisRequest: out of memory !\n");
return 0;
@@ -450,7 +473,7 @@ int mapif_parse_WisRequest(int fd) {
// Wisp/page transmission result
int mapif_parse_WisReply(int fd) {
int id = RFIFOL(fd,2), flag = RFIFOB(fd,6);
- struct WisData *wd = numdb_search(wis_db, id);
+ struct WisData *wd = (struct WisData*)numdb_search(wis_db, id);
if (wd == NULL)
return 0; // This wisp was probably suppress before, because it was timeout of because of target was found on another map-server
@@ -458,7 +481,7 @@ int mapif_parse_WisReply(int fd) {
if ((--wd->count) <= 0 || flag != 1) {
mapif_wis_end(wd, flag); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
numdb_erase(wis_db, id);
- free(wd);
+ aFree(wd);
}
return 0;
@@ -466,7 +489,7 @@ int mapif_parse_WisReply(int fd) {
// Received wisp message from map-server for ALL gm (just copy the message and resends it to ALL map-servers)
int mapif_parse_WisToGM(int fd) {
- unsigned char buf[RFIFOW(fd,2)]; // 0x3003/0x3803 <packet_len>.w <wispname>.24B <min_gm_level>.w <message>.?B
+ unsigned char buf[2048]; // 0x3003/0x3803 <packet_len>.w <wispname>.24B <min_gm_level>.w <message>.?B
memcpy(WBUFP(buf,0), RFIFOP(fd,0), RFIFOW(fd,2));
WBUFW(buf, 0) = 0x3803;
@@ -478,10 +501,10 @@ int mapif_parse_WisToGM(int fd) {
// ƒAƒJƒEƒ“ƒg•Ï”•Û‘¶—v‹
int mapif_parse_AccReg(int fd) {
int j, p;
- struct accreg *reg = numdb_search(accreg_db, RFIFOL(fd,4));
+ struct accreg *reg = (struct accreg*)numdb_search(accreg_db, RFIFOL(fd,4));
if (reg == NULL) {
- if ((reg = calloc(sizeof(struct accreg), 1)) == NULL) {
+ if ((reg = (struct accreg*)aCalloc(sizeof(struct accreg), 1)) == NULL) {
printf("inter: accreg: out of memory !\n");
exit(0);
}
diff --git a/src/char/inter.h b/src/char/inter.h
index 0b6f809d7..636ce31d8 100644
--- a/src/char/inter.h
+++ b/src/char/inter.h
@@ -3,6 +3,7 @@
#define _INTER_H_
int inter_init(const char *file);
+void inter_final();
int inter_save();
int inter_parse_frommap(int fd);
int inter_mapif_init(int fd);
diff --git a/src/char_sql/GNUmakefile b/src/char_sql/GNUmakefile
deleted file mode 100644
index 0f25010d8..000000000
--- a/src/char_sql/GNUmakefile
+++ /dev/null
@@ -1,20 +0,0 @@
-all: char-server_sql
-sql: char-server_sql
-
-COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o ../common/malloc.o ../common/showmsg.o ../common/utils.o ../common/nullpo.o
-COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/db.h ../common/malloc.h ../common/showmsg.h ../common/utils.h ../common/nullpo.h
-
-char-server_sql: char.o inter.o int_party.o int_guild.o int_storage.o int_pet.o strlib.o itemdb.o $(COMMON_OBJ)
- $(CC) -o ../../$@ $^ $(LIB_S)
-
-char.o: char.c char.h strlib.h itemdb.h ../common/showmsg.h
-inter.o: inter.c inter.h int_party.h int_guild.h int_storage.h int_pet.h ../common/mmo.h char.h ../common/socket.h ../common/showmsg.h
-int_party.o: int_party.c int_party.h inter.h ../common/mmo.h char.h ../common/socket.h ../common/timer.h ../common/db.h ../common/showmsg.h
-int_guild.o: int_guild.c int_guild.h inter.h ../common/mmo.h char.h ../common/socket.h ../common/db.h ../common/showmsg.h
-int_storage.o: int_storage.c int_storage.h char.h itemdb.h ../common/showmsg.h
-int_pet.o: int_pet.c int_pet.h inter.h char.h ../common/mmo.h ../common/socket.h ../common/db.h ../common/showmsg.h
-strlib.o: strlib.c strlib.h ../common/showmsg.h
-itemdb.o: itemdb.c itemdb.h ../common/db.h ../common/mmo.h ../common/showmsg.h
-
-clean:
- rm -f *.o ../../char-server_sql \ No newline at end of file
diff --git a/src/char_sql/Makefile b/src/char_sql/Makefile
index 0f25010d8..1741b5ab6 100644
--- a/src/char_sql/Makefile
+++ b/src/char_sql/Makefile
@@ -1,20 +1,20 @@
all: char-server_sql
sql: char-server_sql
-COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o ../common/malloc.o ../common/showmsg.o ../common/utils.o ../common/nullpo.o
-COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/db.h ../common/malloc.h ../common/showmsg.h ../common/utils.h ../common/nullpo.h
+COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o ../common/obj/db.o ../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/utils.o ../common/obj/strlib.o
+COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/db.h ../common/malloc.h ../common/showmsg.h ../common/utils.h ../common/strlib.h
-char-server_sql: char.o inter.o int_party.o int_guild.o int_storage.o int_pet.o strlib.o itemdb.o $(COMMON_OBJ)
+char-server_sql: char.o inter.o int_party.o int_guild.o int_storage.o int_pet.o itemdb.o $(COMMON_OBJ)
$(CC) -o ../../$@ $^ $(LIB_S)
-char.o: char.c char.h strlib.h itemdb.h ../common/showmsg.h
+char.o: char.c char.h ../common/strlib.h itemdb.h ../common/showmsg.h
inter.o: inter.c inter.h int_party.h int_guild.h int_storage.h int_pet.h ../common/mmo.h char.h ../common/socket.h ../common/showmsg.h
int_party.o: int_party.c int_party.h inter.h ../common/mmo.h char.h ../common/socket.h ../common/timer.h ../common/db.h ../common/showmsg.h
int_guild.o: int_guild.c int_guild.h inter.h ../common/mmo.h char.h ../common/socket.h ../common/db.h ../common/showmsg.h
int_storage.o: int_storage.c int_storage.h char.h itemdb.h ../common/showmsg.h
int_pet.o: int_pet.c int_pet.h inter.h char.h ../common/mmo.h ../common/socket.h ../common/db.h ../common/showmsg.h
-strlib.o: strlib.c strlib.h ../common/showmsg.h
itemdb.o: itemdb.c itemdb.h ../common/db.h ../common/mmo.h ../common/showmsg.h
+$(COMMON_OBJ): $(COMMON_H)
clean:
- rm -f *.o ../../char-server_sql \ No newline at end of file
+ rm -f *.o ../../char-server_sql
diff --git a/src/char_sql/char.c b/src/char_sql/char.c
index 91bc604a3..d672bc0eb 100644
--- a/src/char_sql/char.c
+++ b/src/char_sql/char.c
@@ -18,8 +18,6 @@
#include <netdb.h>
#endif
-#include "../common/utils.h"
-#include "../common/nullpo.h"
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
@@ -35,15 +33,18 @@
#include <stdarg.h>
#include "char.h"
-#include "strlib.h"
+#include "../common/utils.h"
+#include "../common/strlib.h"
#include "itemdb.h"
#include "inter.h"
+#include "db.h"
+#include "malloc.h"
#ifdef MEMWATCH
#include "memwatch.h"
#endif
-#define mysql_query(_x, _y) debug_mysql_query(__FILE__, __LINE__, _x, _y)
+static struct dbt *char_db_;
char char_db[256] = "char";
char cart_db[256] = "cart_inventory";
@@ -65,22 +66,18 @@ char guild_storage_db[256] = "guild_storage";
char party_db[256] = "party";
char pet_db[256] = "pet";
char login_db[256] = "login";
+char friend_db[256] = "friends";
+int db_use_sqldbs;
char login_db_account_id[32] = "account_id";
char login_db_level[32] = "level";
int lowest_gm_level = 1;
-int user_count_timer;
-
-unsigned char *SQL_CONF_NAME = "conf/inter_athena.conf";
+char *SQL_CONF_NAME = "conf/inter_athena.conf";
struct mmo_map_server server[MAX_MAP_SERVERS];
int server_fd[MAX_MAP_SERVERS];
-int server_freezeflag[MAX_MAP_SERVERS]; // Map-server anti-freeze system. Counter. 5 ok, 4...0 freezed
-
-int anti_freeze_enable = 0;
-int ANTI_FREEZE_INTERVAL = 6;
int login_fd, char_fd;
char userid[24];
@@ -89,17 +86,21 @@ char server_name[20];
char wisp_server_name[24] = "Server";
int login_ip_set_ = 0;
char login_ip_str[128];
-int login_ip;
+in_addr_t login_ip;
int login_port = 6900;
int char_ip_set_ = 0;
char char_ip_str[128];
-int char_ip;
+int bind_ip_set_ = 0;
+char bind_ip_str[128];
+in_addr_t char_ip;
int char_port = 6121;
int char_maintenance;
int char_new;
int name_ignoring_case = 0; // Allow or not identical name for characters but with a different case by [Yor]
int char_name_option = 0; // Option to know which letters/symbols are authorised in the name of a character (0: all, 1: only those in char_name_letters, 2: all EXCEPT those in char_name_letters) by [Yor]
char char_name_letters[1024] = ""; // list of letters/symbols used to authorise or not a name of a character. by [Yor]
+int char_per_account = 0; //Maximum charas per account (default unlimited) [Sirius]
+
int log_char = 1; // loggin char or not [devil]
int log_inter = 1; // loggin inter or not [devil]
@@ -132,10 +133,11 @@ int auth_fifo_pos = 0;
int check_ip_flag = 1; // It's to check IP of a player between char-server and other servers (part of anti-hacking system)
-//int char_id_count = 150000; // no longer needed, use of MIN_CHAR_ID instead [Ajarn]
+//int char_id_count = 150000; //removed by [Sirius] for new charcreate issue (auto_increment @sql)
struct mmo_charstatus *char_dat;
int char_num,char_max;
int max_connect_user = 0;
+int gm_allow_level = 99;
int autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
int start_zeny = 500;
int start_weapon = 1201;
@@ -154,49 +156,77 @@ int GM_num = 0;
int console = 0;
-char prev_query[65535];
+#define mysql_query(_x, _y) debug_mysql_query(__FILE__, __LINE__, _x, _y)
-char servers_connected = 0;
+//-------------------------------------------------
+// Set Character online/offline [Wizputer]
+//-------------------------------------------------
-// GM Database
-struct dbt *gm_db;
+void set_char_online(int char_id, int account_id) {
+ if ( char_id != 99 ) {
+ sprintf(tmp_sql, "UPDATE `%s` SET `online`='1' WHERE `char_id`='%d'",char_db,char_id);
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (set char online)- %s\n", mysql_error(&mysql_handle));
+ }
+ }
-//----------------------------------------------
-//SQL Commands ( Original by Clownisius ) [Edit: Wizputer]
-//----------------------------------------------
+ if (login_fd <= 0 || session[login_fd]->eof)
+ return;
+ WFIFOW(login_fd,0) = 0x272b;
+ WFIFOL(login_fd,2) = account_id;
+ WFIFOSET(login_fd,6);
-void sql_query(char* query,char function[32]) {
- if(mysql_query(&mysql_handle, query)){
- printf("---------- SQL error report ----------\n");
- printf("MySQL Server Error: %s\n", mysql_error(&mysql_handle));
- printf("Query: %s\n", query);
- printf("In function: %s \n", function);
- printf("\nPrevious query: %s\n", prev_query);
-// if (strcmp(mysql_error(&mysql_handle),"CR_COMMANDS_OUT_OF_SYNC") !=0) printf(" - = Shutting down Char Server = - \n\n");
- printf("-------- End SQL Error Report --------\n");
-// printf("Uncontrolled param: %s",&mysql_handle);
-// if (strcmp(mysql_error(&mysql_handle),"CR_COMMANDS_OUT_OF_SYNC") !=0) exit(1);
+}
+
+void set_all_offline(void) {
+ sprintf(tmp_sql, "SELECT `account_id` FROM `%s` WHERE `online`='1'",char_db);
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (select all online)- %s\n", mysql_error(&mysql_handle));
}
+ sql_res = mysql_store_result(&mysql_handle);
+ if (sql_res) {
+ while((sql_row = mysql_fetch_row(sql_res))) {
+ if ( login_fd > 0 ) {
+ printf("send user offline: %d\n",atoi(sql_row[0]));
+ WFIFOW(login_fd,0) = 0x272c;
+ WFIFOL(login_fd,2) = atoi(sql_row[0]);
+ WFIFOSET(login_fd,6);
+ }
+ }
+ }
- strcpy(prev_query,query);
+ mysql_free_result(sql_res);
+ sprintf(tmp_sql,"UPDATE `%s` SET `online`='0' WHERE `online`='1'", char_db);
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (set_all_offline)- %s\n", mysql_error(&mysql_handle));
+ }
}
-//-----------------------------------------------------
-// Function to suppress control characters in a string.
-//-----------------------------------------------------
-int remove_control_chars(unsigned char *str) {
- int i;
- int change = 0;
+void set_char_offline(int char_id, int account_id) {
+ struct mmo_charstatus *cp;
- for(i = 0; i < strlen(str); i++) {
- if (str[i] < 32) {
- str[i] = '_';
- change = 1;
+ if ( char_id == 99 )
+ sprintf(tmp_sql,"UPDATE `%s` SET `online`='0' WHERE `account_id`='%d'", char_db, account_id);
+ else {
+ cp = (struct mmo_charstatus*)numdb_search(char_db_,char_id);
+ if (cp != NULL) {
+ aFree(cp);
+ numdb_erase(char_db_,char_id);
}
+
+ sprintf(tmp_sql,"UPDATE `%s` SET `online`='0' WHERE `char_id`='%d'", char_db, char_id);
+
+ if (mysql_query(&mysql_handle, tmp_sql))
+ printf("DB server Error (set_char_offline)- %s\n", mysql_error(&mysql_handle));
}
- return change;
+ if (login_fd <= 0 || session[login_fd]->eof)
+ return;
+
+ WFIFOW(login_fd,0) = 0x272c;
+ WFIFOL(login_fd,2) = account_id;
+ WFIFOSET(login_fd,6);
}
//----------------------------------------------------------------------
@@ -204,161 +234,214 @@ int remove_control_chars(unsigned char *str) {
// and returns its level (or 0 if it isn't a GM account or if not found)
//----------------------------------------------------------------------
// Removed since nothing GM related goes on in the char server [CLOWNISIUS]
+int isGM(int account_id) {
+ int i;
-unsigned char isGM(int account_id) {
- unsigned char *level;
-
- level = numdb_search(gm_db, account_id);
- if (level == NULL)
- return 0;
-
- return *level;
-}
-
-static int gmdb_final(void *key,void *data,va_list ap) {
- unsigned char *level;
-
- nullpo_retr(0, level=data);
-
- free(level);
-
+ for(i = 0; i < GM_num; i++)
+ if (gm_account[i].account_id == account_id)
+ return gm_account[i].level;
return 0;
}
-void do_final_gmdb(void) {
- if(gm_db){
- numdb_final(gm_db,gmdb_final);
- gm_db=NULL;
+void read_gm_account(void) {
+ if (gm_account != NULL)
+ aFree(gm_account);
+ GM_num = 0;
+
+ sprintf(tmp_lsql, "SELECT `%s`,`%s` FROM `%s` WHERE `%s`>='%d'",login_db_account_id,login_db_level,login_db,login_db_level,lowest_gm_level);
+ if (mysql_query(&lmysql_handle, tmp_lsql)) {
+ printf("DB server Error (select %s to Memory)- %s\n",login_db,mysql_error(&lmysql_handle));
+ }
+ lsql_res = mysql_store_result(&lmysql_handle);
+ if (lsql_res) {
+ gm_account = (struct gm_account*)aCalloc(sizeof(struct gm_account) * mysql_num_rows(lsql_res), 1);
+ while ((lsql_row = mysql_fetch_row(lsql_res))) {
+ gm_account[GM_num].account_id = atoi(lsql_row[0]);
+ gm_account[GM_num].level = atoi(lsql_row[1]);
+ GM_num++;
+ }
}
-}
-
-int read_gm_accounts(int fd, int len) {
- GM_num = RFIFOW(fd,2);
-
- if(len < (6+5*GM_num))
- return -1;
- int i=0,account_id=0;
- unsigned char *level;
-
- if (gm_db)
- do_final_gmdb();
+ mysql_free_result(lsql_res);
+ mapif_send_gmaccounts();
+}
- gm_db = numdb_init();
+// Insert friends list
+int insert_friends(int char_id){
+ int i;
+ char *tmp_p = tmp_sql;
- WFIFOW(fd,0) = 0x2b99;
- WFIFOW(fd,2) = GM_num;
+ tmp_p += sprintf(tmp_p, "REPLACE INTO `%s` (`id`, `account_id`",friend_db);
- if(GM_num) {
- for(i=0;i<GM_num;i++) {
- level = malloc(sizeof(unsigned char));
+ for (i=0;i<20;i++)
+ tmp_p += sprintf(tmp_p, ", `friend_id%d`, `name%d`", i, i);
- *level = RFIFOB(fd,(10+5*(GM_num-1)));
- account_id = RFIFOW(fd,(6+5*(GM_num-1)));
+ tmp_p += sprintf(tmp_p, ") VALUES (NULL, '%d'", char_id);
- numdb_insert(gm_db, account_id, level);
+ for (i=0;i<20;i++)
+ tmp_p += sprintf(tmp_p, ", '0', ''");
- WFIFOL(fd,6+5*i) = account_id;
- WFIFOB(fd,10+5*i) = *level;
- }
- }
+ tmp_p += sprintf(tmp_p, ")");
- WFIFOSET(fd,6+5*i);
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (insert `friend`)- %s\n", mysql_error(&mysql_handle));
+ return 0;
+ }
+return 1;
+}
- return 0;
+int compare_item(struct item *a, struct item *b) {
+ return (
+ (a->id == b->id) &&
+ (a->nameid == b->nameid) &&
+ (a->amount == b->amount) &&
+ (a->equip == b->equip) &&
+ (a->identify == b->identify) &&
+ (a->refine == b->refine) &&
+ (a->attribute == b->attribute) &&
+ (a->card[0] == b->card[0]) &&
+ (a->card[1] == b->card[1]) &&
+ (a->card[2] == b->card[2]) &&
+ (a->card[3] == b->card[3]));
}
//=====================================================================================================
int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
- int i=0;
- int eqcount=1;
- char temp_str[32];
+ int i=0,party_exist,guild_exist;
+// int eqcount=1;
+// int noteqcount=1;
+ int count = 0;
+ int diff = 0;
+ char temp_str[1024];
+ char *tmp_p = tmp_sql;
+ struct mmo_charstatus *cp;
+ struct itemtmp mapitem[MAX_GUILD_STORAGE];
- struct itemtemp mapitem;
if (char_id!=p->char_id) return 0;
- save_flag = p->char_id;
+ cp = (struct mmo_charstatus*)numdb_search(char_db_,char_id);
- #ifdef DEBUG
+ if (cp == NULL) {
+ cp = (struct mmo_charstatus *) aMalloc(sizeof(struct mmo_charstatus));
+ memset(cp, 0, sizeof(struct mmo_charstatus));
+ numdb_insert(char_db_, char_id,cp);
+ }
+
+ save_flag = p->char_id;
printf("(\033[1;32m%d\033[0m) %s \trequest save char data - ",char_id,char_dat[0].name);
- #endif
- sql_query("START TRANSACTION","mmo_char_tosql");
+//for(testcount=1;testcount<50;testcount++){//---------------------------test count--------------------
+// printf("test count : %d\n", testcount);
+// eqcount=1;
+// noteqcount=1;
+// dbeqcount=1;
+// dbnoteqcount=1;
+//-----------------------------------------------------------------------------------------------------
//=========================================map inventory data > memory ===============================
+ diff = 0;
+
//map inventory data
for(i=0;i<MAX_INVENTORY;i++){
+ if (!compare_item(&p->inventory[i], &cp->inventory[i]))
+ diff = 1;
if(p->inventory[i].nameid>0){
- mapitem.equip[eqcount].flag=0;
- mapitem.equip[eqcount].id = p->inventory[i].id;
- mapitem.equip[eqcount].nameid=p->inventory[i].nameid;
- mapitem.equip[eqcount].amount = p->inventory[i].amount;
- mapitem.equip[eqcount].equip = p->inventory[i].equip;
- mapitem.equip[eqcount].identify = p->inventory[i].identify;
- mapitem.equip[eqcount].refine = p->inventory[i].refine;
- mapitem.equip[eqcount].attribute = p->inventory[i].attribute;
- mapitem.equip[eqcount].card[0] = p->inventory[i].card[0];
- mapitem.equip[eqcount].card[1] = p->inventory[i].card[1];
- mapitem.equip[eqcount].card[2] = p->inventory[i].card[2];
- mapitem.equip[eqcount].card[3] = p->inventory[i].card[3];
- eqcount++;
+ mapitem[count].flag=0;
+ mapitem[count].id = p->inventory[i].id;
+ mapitem[count].nameid=p->inventory[i].nameid;
+ mapitem[count].amount = p->inventory[i].amount;
+ mapitem[count].equip = p->inventory[i].equip;
+ mapitem[count].identify = p->inventory[i].identify;
+ mapitem[count].refine = p->inventory[i].refine;
+ mapitem[count].attribute = p->inventory[i].attribute;
+ mapitem[count].card[0] = p->inventory[i].card[0];
+ mapitem[count].card[1] = p->inventory[i].card[1];
+ mapitem[count].card[2] = p->inventory[i].card[2];
+ mapitem[count].card[3] = p->inventory[i].card[3];
+ count++;
}
}
-
- memitemdata_to_sql2(mapitem, eqcount, p->char_id,TABLE_INVENTORY);
-
- #ifdef DEBUG
- printf("Char [%s] - Save item data to SQL!\n",p->name);
- #endif
+ //printf("- Save item data to MySQL!\n");
+ if (diff)
+ memitemdata_to_sql(mapitem, count, p->char_id,TABLE_INVENTORY);
//=========================================map cart data > memory ====================================
- eqcount=1;
+// eqcount=1;
+// noteqcount=1;
+ count = 0;
+ diff = 0;
//map cart data
for(i=0;i<MAX_CART;i++){
+ if (!compare_item(&p->cart[i], &cp->cart[i]))
+ diff = 1;
if(p->cart[i].nameid>0){
- mapitem.equip[eqcount].flag=0;
- mapitem.equip[eqcount].id = p->cart[i].id;
- mapitem.equip[eqcount].nameid=p->cart[i].nameid;
- mapitem.equip[eqcount].amount = p->cart[i].amount;
- mapitem.equip[eqcount].equip = p->cart[i].equip;
- mapitem.equip[eqcount].identify = p->cart[i].identify;
- mapitem.equip[eqcount].refine = p->cart[i].refine;
- mapitem.equip[eqcount].attribute = p->cart[i].attribute;
- mapitem.equip[eqcount].card[0] = p->cart[i].card[0];
- mapitem.equip[eqcount].card[1] = p->cart[i].card[1];
- mapitem.equip[eqcount].card[2] = p->cart[i].card[2];
- mapitem.equip[eqcount].card[3] = p->cart[i].card[3];
- eqcount++;
+ mapitem[count].flag=0;
+ mapitem[count].id = p->cart[i].id;
+ mapitem[count].nameid=p->cart[i].nameid;
+ mapitem[count].amount = p->cart[i].amount;
+ mapitem[count].equip = p->cart[i].equip;
+ mapitem[count].identify = p->cart[i].identify;
+ mapitem[count].refine = p->cart[i].refine;
+ mapitem[count].attribute = p->cart[i].attribute;
+ mapitem[count].card[0] = p->cart[i].card[0];
+ mapitem[count].card[1] = p->cart[i].card[1];
+ mapitem[count].card[2] = p->cart[i].card[2];
+ mapitem[count].card[3] = p->cart[i].card[3];
+ count++;
}
}
- memitemdata_to_sql2(mapitem, eqcount, p->char_id,TABLE_CART);
+ //printf("- Save cart data to MySQL!\n");
+ if (diff)
+ memitemdata_to_sql(mapitem, count, p->char_id,TABLE_CART);
- #ifdef DEBUG
- printf("Char [%s] - Save cart data to SQL!\n",p->name);
- #endif
+//=====================================================================================================
+ if ((p->base_exp != cp->base_exp) || (p->class_ != cp->class_) ||
+ (p->base_level != cp->base_level) || (p->job_level != cp->job_level) ||
+ (p->job_exp != cp->job_exp) || (p->zeny != cp->zeny) ||
+ (p->last_point.x != cp->last_point.x) || (p->last_point.y != cp->last_point.y) ||
+ (p->max_hp != cp->max_hp) || (p->hp != cp->hp) ||
+ (p->max_sp != cp->max_sp) || (p->sp != cp->sp) ||
+ (p->status_point != cp->status_point) || (p->skill_point != cp->skill_point) ||
+ (p->str != cp->str) || (p->agi != cp->agi) || (p->vit != cp->vit) ||
+ (p->int_ != cp->int_) || (p->dex != cp->dex) || (p->luk != cp->luk) ||
+ (p->option != cp->option) || (p->karma != cp->karma) || (p->manner != cp->manner) ||
+ (p->party_id != cp->party_id) || (p->guild_id != cp->guild_id) ||
+ (p->pet_id != cp->pet_id) || (p->hair != cp->hair) || (p->hair_color != cp->hair_color) ||
+ (p->clothes_color != cp->clothes_color) || (p->weapon != cp->weapon) ||
+ (p->shield != cp->shield) || (p->head_top != cp->head_top) ||
+ (p->head_mid != cp->head_mid) || (p->head_bottom != cp->head_bottom) ||
+ (p->partner_id != cp->partner_id) || (p->father != cp->father) ||
+ (p->mother != cp->mother) || (p->child != cp->child)) {
+
+//}//---------------------------test count------------------------------
//check party_exist
- sprintf(tmp_sql, "SELECT count(*) FROM `%s` WHERE `party_id` = '%d'",party_db, p->party_id);
- sql_query(tmp_sql,"mmo_char_tosql");
-
- if((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res)))
- if(!atoi(sql_row[0]))
- p->party_id=0;
-
+ party_exist=0;
+ sprintf(tmp_sql, "SELECT count(*) FROM `%s` WHERE `party_id` = '%d'",party_db, p->party_id); // TBR
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle);
+ sql_row = mysql_fetch_row(sql_res);
+ if (sql_row) party_exist = atoi(sql_row[0]);
mysql_free_result(sql_res);
//check guild_exist
- sprintf(tmp_sql, "SELECT count(*) FROM `%s` WHERE `guild_id` = '%d'",guild_db, p->guild_id);
- sql_query(tmp_sql,"mmo_char_tosql");
-
- if((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res)))
- if(!atoi(sql_row[0]))
- p->guild_id=0;
-
+ guild_exist=0;
+ sprintf(tmp_sql, "SELECT count(*) FROM `%s` WHERE `guild_id` = '%d'",guild_db, p->guild_id); // TBR
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle);
+ sql_row = mysql_fetch_row(sql_res);
+ if (sql_row) guild_exist = atoi(sql_row[0]);
mysql_free_result(sql_res);
+ if (guild_exist==0) p->guild_id=0;
+ if (party_exist==0) p->party_id=0;
+
//sql query
//`char`( `char_id`,`account_id`,`char_num`,`name`,`class`,`base_level`,`job_level`,`base_exp`,`job_exp`,`zeny`, //9
//`str`,`agi`,`vit`,`int`,`dex`,`luk`, //15
@@ -373,8 +456,8 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
"`str`='%d',`agi`='%d',`vit`='%d',`int`='%d',`dex`='%d',`luk`='%d',"
"`option`='%d',`karma`='%d',`manner`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d',"
"`hair`='%d',`hair_color`='%d',`clothes_color`='%d',`weapon`='%d',`shield`='%d',`head_top`='%d',`head_mid`='%d',`head_bottom`='%d',"
- "`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d',`partner_id`='%d' WHERE `account_id`='%d' AND `char_id` = '%d'",
- char_db, p->class, p->base_level, p->job_level,
+ "`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d',`partner_id`='%d', `father`='%d', `mother`='%d', `child`='%d' WHERE `account_id`='%d' AND `char_id` = '%d'",
+ char_db, p->class_, p->base_level, p->job_level,
p->base_exp, p->job_exp, p->zeny,
p->max_hp, p->hp, p->max_sp, p->sp, p->status_point, p->skill_point,
p->str, p->agi, p->vit, p->int_, p->dex, p->luk,
@@ -382,351 +465,252 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
p->hair, p->hair_color, p->clothes_color,
p->weapon, p->shield, p->head_top, p->head_mid, p->head_bottom,
p->last_point.map, p->last_point.x, p->last_point.y,
- p->save_point.map, p->save_point.x, p->save_point.y, p->partner_id, p->account_id, p->char_id
+ p->save_point.map, p->save_point.x, p->save_point.y, p->partner_id, p->father, p->mother,
+ p->child, p->account_id, p->char_id
);
- sql_query(tmp_sql,"mmo_char_tosql");
+ if(mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (update `char`)- %s\n", mysql_error(&mysql_handle));
+ }
- #ifdef DEBUG
- printf("Char [%s] - Saved Char data to SQL!\n",p->name);
- #endif
+ }
- sprintf(tmp_sql,"DELETE FROM `%s` WHERE `char_id`='%d'",memo_db,char_id);
- sql_query(tmp_sql,"mmo_char_tosql");
+ diff = 0;
- sprintf(tmp_sql,"INSERT INTO `%s`(`char_id`,`map`,`x`,`y`) VALUES ",memo_db);
for(i=0;i<10;i++){
- if(i)
- sprintf(tmp_sql,"%s,",tmp_sql);
+ if((strcmp(p->memo_point[i].map,cp->memo_point[i].map) == 0) && (p->memo_point[i].x == cp->memo_point[i].x) && (p->memo_point[i].y == cp->memo_point[i].y))
+ continue;
+ diff = 1;
+ break;
+ }
- if(p->memo_point[i].map[0])
- sprintf(tmp_sql,"%s('%d', '%s', '%d', '%d')",tmp_sql,
- char_id, p->memo_point[i].map, p->memo_point[i].x, p->memo_point[i].y);
+ if (diff) {
+ //printf("- Save memo data to MySQL!\n");
+ //`memo` (`memo_id`,`char_id`,`map`,`x`,`y`)
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `char_id`='%d'",memo_db, p->char_id);
+ if(mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (delete `memo`)- %s\n", mysql_error(&mysql_handle));
}
- sql_query(tmp_sql,"mmo_char_tosql");
+ //insert here.
+ for(i=0;i<10;i++){
+ if(p->memo_point[i].map[0]){
+ sprintf(tmp_sql,"INSERT INTO `%s`(`char_id`,`map`,`x`,`y`) VALUES ('%d', '%s', '%d', '%d')",
+ memo_db, char_id, p->memo_point[i].map, p->memo_point[i].x, p->memo_point[i].y);
+ if(mysql_query(&mysql_handle, tmp_sql))
+ printf("DB server Error (insert `memo`)- %s\n", mysql_error(&mysql_handle));
+ }
+ }
+ }
- #ifdef DEBUG
- printf("Char [%s] - Saved memo data to SQL!\n",p->name);
- #endif
+ diff = 0;
+ for(i=0;i<MAX_SKILL;i++) {
+ if ((p->skill[i].lv != 0) && (p->skill[i].id == 0))
+ p->skill[i].id = i; // Fix skill tree
- sprintf(tmp_sql,"DELETE FROM `%s` WHERE `char_id`='%d'",skill_db,char_id);
- sql_query(tmp_sql,"mmo_char_tosql");
+ if((p->skill[i].id != cp->skill[i].id) || (p->skill[i].lv != cp->skill[i].lv) ||
+ (p->skill[i].flag != cp->skill[i].flag)) {
+ diff = 1;
+ break;
+ }
+ }
- sprintf(tmp_sql,"INSERT INTO `%s`(`char_id`, `id`, `lv`) VALUES ",skill_db);
+ if (diff) {
+ //printf("- Save skill data to MySQL!\n");
+ //`skill` (`char_id`, `id`, `lv`)
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `char_id`='%d'",skill_db, p->char_id);
+ if(mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (delete `skill`)- %s\n", mysql_error(&mysql_handle));
+ }
+ //printf("- Insert skill \n");
+ //insert here.
for(i=0;i<MAX_SKILL;i++){
if(p->skill[i].id){
if (p->skill[i].id && p->skill[i].flag!=1) {
- if(i)
- sprintf(tmp_sql,"%s,",tmp_sql);
-
- sprintf(tmp_sql,"%s('%d', '%d','%d')",tmp_sql,
- char_id, p->skill[i].id, (p->skill[i].flag==0)?p->skill[i].lv:p->skill[i].flag-2);
+ sprintf(tmp_sql,"INSERT INTO `%s`(`char_id`, `id`, `lv`) VALUES ('%d', '%d','%d')",
+ skill_db, char_id, p->skill[i].id, (p->skill[i].flag==0)?p->skill[i].lv:p->skill[i].flag-2);
+ if(mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (insert `skill`)- %s\n", mysql_error(&mysql_handle));
+ }
}
}
}
+ }
- sql_query(tmp_sql,"mmo_char_tosql");
-
- #ifdef DEBUG
- printf("Char [%s] - Save skill data to SQL!\n",p->name);
- #endif
+ diff = 0;
+ for(i=0;i<p->global_reg_num;i++) {
+ if ((p->global_reg[i].str == NULL) && (cp->global_reg[i].str == NULL))
+ continue;
+ if (((p->global_reg[i].str == NULL) != (cp->global_reg[i].str == NULL)) ||
+ (p->global_reg[i].value != cp->global_reg[i].value) ||
+ strcmp(p->global_reg[i].str, cp->global_reg[i].str) != 0) {
+ diff = 1;
+ break;
+ }
+ }
- sprintf(tmp_sql,"DELETE FROM `%s` WHERE `char_id`='%d' AND `type`='3'",reg_db,char_id);
- sql_query(tmp_sql,"mmo_char_tosql");
+ if (diff) {
+ //printf("- Save global_reg_value data to MySQL!\n");
+ //`global_reg_value` (`char_id`, `str`, `value`)
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'",reg_db, p->char_id);
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (delete `global_reg_value`)- %s\n", mysql_error(&mysql_handle));
+ }
- sprintf(tmp_sql,"INSERT INTO `%s`(`char_id`, `str`, `value`) VALUES ",reg_db);
+ //insert here.
for(i=0;i<p->global_reg_num;i++){
if (p->global_reg[i].str) {
if(p->global_reg[i].value !=0){
- if(i)
- sprintf(tmp_sql,"%s,",tmp_sql);
-
- sprintf(tmp_sql,"%s('%d', '%s','%d')",tmp_sql,
- char_id, jstrescapecpy(temp_str,(unsigned char*)p->global_reg[i].str), p->global_reg[i].value);
+ sprintf(tmp_sql,"INSERT INTO `%s` (`char_id`, `str`, `value`) VALUES ('%d', '%s','%d')",
+ reg_db, char_id, jstrescapecpy(temp_str,p->global_reg[i].str), p->global_reg[i].value);
+ if(mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (insert `global_reg_value`)- %s\n", mysql_error(&mysql_handle));
+ }
}
}
}
+ }
- sql_query(tmp_sql,"mmo_char_tosql");
-
- sql_query("COMMIT","mmo_char_tosql");
-
- #ifdef DEBUG
- printf("Char [%s] - Save global reg data to SQL!\n",p->name);
- printf("Char [%s] - Saving char is done.\n",p->name);
- #endif
+ // Friends list
+ // account_id, friend_id0, name0, ...
+ #if 0
+ tmp_p += sprintf(tmp_p, "REPLACE INTO `%s` (`id`, `account_id`",friend_db);
- save_flag = 0;
+ diff = 0;
- return 0;
-}
+ for (i=0;i<20;i++)
+ tmp_p += sprintf(tmp_p, ", `friend_id%d`, `name%d`", i, i);
-int memitemdata_to_sql2(struct itemtemp mapitem, int eqcount, int char_id, int tableswitch){
- //equ
- int i;
- char tablename[16];
- char selectoption[16];
+ tmp_p += sprintf(tmp_p, ") VALUES (NULL, '%d'", char_id);
- switch (tableswitch){
- case TABLE_INVENTORY:
- sprintf(tablename,"%s",inventory_db);
- sprintf(selectoption,"char_id");
- break;
- case TABLE_CART:
- sprintf(tablename,"%s",cart_db);
- sprintf(selectoption,"char_id");
- break;
- case TABLE_STORAGE:
- sprintf(tablename,"%s",storage_db);
- sprintf(selectoption,"account_id");
- break;
- case TABLE_GUILD_STORAGE:
- sprintf(tablename,"%s",guild_storage_db);
- sprintf(selectoption,"guild_id");
- break;
- }
-
- sprintf(tmp_sql,"DELETE FROM `%s` WHERE `%s`='%d'",tablename,selectoption,char_id);
- sql_query(tmp_sql,"memitemdata_to_sql");
-
- //==============================================Memory data > SQL ===============================
+ for (i=0;i<20;i++) {
+ tmp_p += sprintf(tmp_p, ", '%d', '%s'", p->friend_id[i], p->friend_name[i]);
+ if ((p->friend_id[i] != cp->friend_id[i]) ||
+ strcmp(p->friend_name[i], cp->friend_name[i]))
+ diff = 1;
+ }
- sprintf(tmp_sql,"INSERT INTO `%s` (`%s`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`card0`,`card1`,`card2`,`card3`) VALUES ",tablename,selectoption);
+ tmp_p += sprintf(tmp_p, ")");
+ #else // [Dino9021]
+ tmp_p += sprintf(tmp_p, "UPDATE `%s` SET ",friend_db);
- for(i=1;i<eqcount;i++){
- if(mapitem.equip[i].flag == 1) break;
+ diff = 0;
+
+ for (i=0;i<20;i++) {
+ if (i>0)
+ tmp_p += sprintf(tmp_p, ", ");
- if(i!=1)
- sprintf(tmp_sql,"%s,",tmp_sql);
+ tmp_p += sprintf(tmp_p, "`friend_id%d`='%d', `name%d`='%s'", i, p->friend_id[i], i, p->friend_name[i]);
- sprintf(tmp_sql,"%s('%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d')",tmp_sql,char_id,
- mapitem.equip[i].nameid, mapitem.equip[i].amount, mapitem.equip[i].equip, mapitem.equip[i].identify,
- mapitem.equip[i].refine,mapitem.equip[i].attribute, mapitem.equip[i].card[0],mapitem.equip[i].card[1],
- mapitem.equip[i].card[2],mapitem.equip[i].card[3]);
+ if ((p->friend_id[i] != cp->friend_id[i]) || strcmp(p->friend_name[i], cp->friend_name[i]))
+ diff = 1;
+ }
- mapitem.equip[i].flag=1;
- }
+ tmp_p += sprintf(tmp_p, " where account_id='%d';", char_id);
+ #endif
- sql_query(tmp_sql,"memitemdata_to_sql");
+ if (diff)
+ mysql_query(&mysql_handle, tmp_sql);
- #ifdef DEBUG
- printf("Char [%d] - Saved Eqip Item Data to SQL!\n",char_id);
- #endif
+ printf("saving char is done.\n");
+ save_flag = 0;
+ memcpy(cp, p, sizeof(struct mmo_charstatus));
- return 0;
+ return 0;
}
-int memitemdata_to_sql(struct itemtemp mapitem, int eqcount, int noteqcount, int char_id, int tableswitch){
- //equ
- int i, j;
- int dbeqcount = 1;
- int dbnoteqcount = 1;
- struct itemtemp dbitem;
- char tablename[16];
+// [Ilpalazzo-sama]
+int memitemdata_to_sql(struct itemtmp mapitem[], int count, int char_id, int tableswitch)
+{
+ int i, flag, id;
+ char *tablename;
char selectoption[16];
- switch (tableswitch){
+ switch (tableswitch) {
case TABLE_INVENTORY:
- sprintf(tablename,"%s",inventory_db);
+ tablename = inventory_db; // no need for sprintf here as *_db are char*.
sprintf(selectoption,"char_id");
break;
case TABLE_CART:
- sprintf(tablename,"%s",cart_db);
+ tablename = cart_db;
sprintf(selectoption,"char_id");
break;
case TABLE_STORAGE:
- sprintf(tablename,"%s",storage_db);
+ tablename = storage_db;
sprintf(selectoption,"account_id");
break;
case TABLE_GUILD_STORAGE:
- sprintf(tablename,"%s",guild_storage_db);
+ tablename = guild_storage_db;
sprintf(selectoption,"guild_id");
break;
+ default:
+ printf("Invalid table name!\n");
+ return 1;
}
//printf("Working Table : %s \n",tablename);
//=======================================mysql database data > memory===============================================
-
sprintf(tmp_sql, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3` "
- "FROM `%s` WHERE `%s`='%d'",tablename ,selectoption ,char_id);
+ "FROM `%s` WHERE `%s`='%d'", tablename, selectoption, char_id);
if (mysql_query(&mysql_handle, tmp_sql)) {
printf("DB server Error (select `%s` to Memory)- %s\n",tablename ,mysql_error(&mysql_handle));
+ return 1;
}
sql_res = mysql_store_result(&mysql_handle);
if (sql_res) {
- for(i=0;(sql_row = mysql_fetch_row(sql_res));i++){
- if (itemdb_isequip(atoi(sql_row[1]))==1){
- dbitem.equip[dbeqcount].flag=0;
- dbitem.equip[dbeqcount].id = atoi(sql_row[0]);
- dbitem.equip[dbeqcount].nameid = atoi(sql_row[1]);
- dbitem.equip[dbeqcount].amount = atoi(sql_row[2]);
- dbitem.equip[dbeqcount].equip = atoi(sql_row[3]);
- dbitem.equip[dbeqcount].identify = atoi(sql_row[4]);
- dbitem.equip[dbeqcount].refine = atoi(sql_row[5]);
- dbitem.equip[dbeqcount].attribute = atoi(sql_row[6]);
- dbitem.equip[dbeqcount].card[0] = atoi(sql_row[7]);
- dbitem.equip[dbeqcount].card[1] = atoi(sql_row[8]);
- dbitem.equip[dbeqcount].card[2] = atoi(sql_row[9]);
- dbitem.equip[dbeqcount].card[3] = atoi(sql_row[10]);
- dbeqcount++;
- }else {
- dbitem.notequip[dbnoteqcount].flag=0;
- dbitem.notequip[dbnoteqcount].id = atoi(sql_row[0]);
- dbitem.notequip[dbnoteqcount].nameid = atoi(sql_row[1]);
- dbitem.notequip[dbnoteqcount].amount = atoi(sql_row[2]);
- dbitem.notequip[dbnoteqcount].equip = atoi(sql_row[3]);
- dbitem.notequip[dbnoteqcount].identify = atoi(sql_row[4]);
- dbitem.notequip[dbnoteqcount].refine = atoi(sql_row[5]);
- dbitem.notequip[dbnoteqcount].attribute = atoi(sql_row[6]);
- dbitem.notequip[dbnoteqcount].card[0] = atoi(sql_row[7]);
- dbitem.notequip[dbnoteqcount].card[1] = atoi(sql_row[8]);
- dbitem.notequip[dbnoteqcount].card[2] = atoi(sql_row[9]);
- dbitem.notequip[dbnoteqcount].card[3] = atoi(sql_row[10]);
- dbnoteqcount++;
- }
- }
- mysql_free_result(sql_res);
- }
-
- //==============================================Memory data > SQL ===============================
- //======================================Equip ITEM=======================================
- if((eqcount==1) && (dbeqcount==1)){//printf("%s Equip Empty\n",tablename);
- //item empty
- } else {
-
- for(i=1;i<eqcount;i++){
- for(j=1;j<dbeqcount;j++){
- if(mapitem.equip[i].flag==1) break;
- if(!(dbitem.equip[j].flag==1)){
- if(mapitem.equip[i].nameid==dbitem.equip[j].nameid){
- if ((mapitem.equip[i].equip==dbitem.equip[j].equip) && (mapitem.equip[i].identify==dbitem.equip[j].identify) && (mapitem.equip[i].amount==dbitem.equip[j].amount) &&
-
- (mapitem.equip[i].refine==dbitem.equip[j].refine) && (mapitem.equip[i].attribute==dbitem.equip[j].attribute) && (mapitem.equip[i].card[0]==dbitem.equip[j].card[0]) &&
- (mapitem.equip[i].card[1]==dbitem.equip[j].card[1]) && (mapitem.equip[i].card[2]==dbitem.equip[j].card[2]) && (mapitem.equip[i].card[3]==dbitem.equip[j].card[3])) {
- mapitem.equip[i].flag = 1;
- dbitem.equip[j].flag = 1;
- //printf("the same item : %d , equip : %d , i : %d , flag : %d\n", mapitem.equip[i].nameid,mapitem.equip[i].equip , i, mapitem.equip[i].flag); //DEBUG-STRING
- } else {
+ while ((sql_row = mysql_fetch_row(sql_res))) {
+ flag = 0;
+ id = atoi(sql_row[0]);
+ for(i = 0; i < count; i++) {
+ if(mapitem[i].flag == 1)
+ continue;
+ if(mapitem[i].nameid == atoi(sql_row[1])) { // produced items fixup
+ if((mapitem[i].equip == atoi(sql_row[3])) &&
+ (mapitem[i].identify == atoi(sql_row[4])) &&
+ (mapitem[i].amount == atoi(sql_row[2])) &&
+ (mapitem[i].refine == atoi(sql_row[5])) &&
+ (mapitem[i].attribute == atoi(sql_row[6])) &&
+ (mapitem[i].card[0] == atoi(sql_row[7])) &&
+ (mapitem[i].card[1] == atoi(sql_row[8])) &&
+ (mapitem[i].card[2] == atoi(sql_row[9])) &&
+ (mapitem[i].card[3] == atoi(sql_row[10]))) {
+ //printf("the same item : %d , equip : %d , i : %d , flag : %d\n", mapitem.equip[i].nameid,mapitem.equip[i].equip , i, mapitem.equip[i].flag); //DEBUG-STRING
+ } else {
+//==============================================Memory data > SQL ===============================
+ if(itemdb_isequip(mapitem[i].nameid) || (mapitem[i].card[0] == atoi(sql_row[7]))) {
sprintf(tmp_sql,"UPDATE `%s` SET `equip`='%d', `identify`='%d', `refine`='%d',"
- "`attribute`='%d', `card0`='%d', `card1`='%d', `card2`='%d', `card3`='%d', `amount`='%d' WHERE `id`='%d' LIMIT 1",
- tablename, mapitem.equip[i].equip, mapitem.equip[i].identify, mapitem.equip[i].refine,mapitem.equip[i].attribute, mapitem.equip[i].card[0],
- mapitem.equip[i].card[1], mapitem.equip[i].card[2], mapitem.equip[i].card[3], mapitem.equip[i].amount, dbitem.equip[j].id);
- //printf("%s\n",tmp_sql);
+ "`attribute`='%d', `card0`='%d', `card1`='%d', `card2`='%d', `card3`='%d', `amount`='%d' WHERE `id`='%d' LIMIT 1",
+ tablename, mapitem[i].equip, mapitem[i].identify, mapitem[i].refine, mapitem[i].attribute, mapitem[i].card[0],
+ mapitem[i].card[1], mapitem[i].card[2], mapitem[i].card[3], mapitem[i].amount, id);
if(mysql_query(&mysql_handle, tmp_sql))
printf("DB server Error (UPdate `equ %s`)- %s\n", tablename, mysql_error(&mysql_handle));
- mapitem.equip[i].flag=1;
- dbitem.equip[j].flag=1;
- //printf("not the same item : %d ; i : %d ; flag : %d\n", mapitem.equip[i].nameid, i, mapitem.equip[i].flag);
}
+ //printf("not the same item : %d ; i : %d ; flag : %d\n", mapitem.equip[i].nameid, i, mapitem.equip[i].flag);
}
+ flag = mapitem[i].flag = 1;
+ break;
}
}
- }
-
- //printf("dbeqcount = %d\n",dbeqcount);
-
- for(i=1;i<dbeqcount;i++){
- //printf("dbitem.equip[i].flag = %d , dbitem.equip[i].id = %d\n",dbitem.equip[i].flag,dbitem.equip[i].id);
- if (!(dbitem.equip[i].flag == 1)) {
- sprintf(tmp_sql,"DELETE from `%s` where `id`='%d'",tablename , dbitem.equip[i].id);
- //printf("%s", tmp_sql);
- if(mysql_query(&mysql_handle, tmp_sql))
- printf("DB server Error (DELETE `equ %s`)- %s\n", tablename ,mysql_error(&mysql_handle));
+ if(!flag) {
+ sprintf(tmp_sql,"DELETE from `%s` where `id`='%d'", tablename, id);
+ if(mysql_query(&mysql_handle, tmp_sql))
+ printf("DB server Error (DELETE `equ %s`)- %s\n", tablename, mysql_error(&mysql_handle));
}
}
- for(i=1;i<eqcount;i++){
- if(!(mapitem.equip[i].flag==1)){
- sprintf(tmp_sql,"INSERT INTO `%s`(`%s`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`)"
- " VALUES ( '%d','%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
- tablename, selectoption, char_id, mapitem.equip[i].nameid, mapitem.equip[i].amount, mapitem.equip[i].equip, mapitem.equip[i].identify, mapitem.equip[i].refine,
- mapitem.equip[i].attribute, mapitem.equip[i].card[0], mapitem.equip[i].card[1], mapitem.equip[i].card[2], mapitem.equip[i].card[3]);
- //printf("%s", tmp_sql);
- if(mysql_query(&mysql_handle, tmp_sql))
- printf("DB server Error (INSERT `equ %s`)- %s\n",tablename ,mysql_error(&mysql_handle));
- }
- }
-
- //======================================DEBUG=================================================
-
-// gettimeofday(&tv,NULL);
-// strftime(tmpstr,24,"%Y-%m-%d %H:%M:%S",localtime(&(tv.tv_sec)));
-// printf("\n\n");
-// printf("Working Table Name : EQU %s, Count : map %3d | db %3d \n",tablename ,eqcount ,dbeqcount);
-// printf("*********************************************************************************\n");
-// printf("======================================MAP===================Char ID %10d===\n",char_id);
-// printf("==flag ===name ===equip===ident===amoun===attri===card0===card1===card2===card3==\n");
-// for(j=1;j<eqcount;j++)
-// printf("| %5d | %5d | %5d | %5d | %5d | %5d | %5d | %5d | %5d | %5d |\n", mapitem.equip[j].flag,mapitem.equip[j].nameid, mapitem.equip[j].equip, mapitem.equip[j].identify, mapitem.equip[j].refine,mapitem.equip[j].attribute, mapitem.equip[j].card[0], mapitem.equip[j].card[1], mapitem.equip[j].card[2], mapitem.equip[j].card[3]);
-// printf("======================================DB=========================================\n");
-// printf("==flag ===name ===equip===ident===refin===attri===card0===card1===card2===card3==\n");
-// for(j=1;j<dbeqcount;j++)
-// printf("| %5d | %5d | %5d | %5d | %5d | %5d | %5d | %5d | %5d | %5d |\n", dbitem.equip[j].flag ,dbitem.equip[j].nameid, dbitem.equip[j].equip, dbitem.equip[j].identify, dbitem.equip[j].amount,dbitem.equip[j].attribute, dbitem.equip[j].card[0], dbitem.equip[j].card[1], dbitem.equip[j].card[2], dbitem.equip[j].card[3]);
-// printf("=================================================================================\n");
-// printf("=================================================Data Time %s===\n", tmpstr);
-// printf("=================================================================================\n");
-
+ mysql_free_result(sql_res);
}
- //======================================DEBUG==================================================
-
- //=============================Not Equip ITEM==========================================
- if((noteqcount==1) && (dbnoteqcount==1)){
- //printf("%s Not Equip Empty\n",tablename);
- //item empty
- } else {
-
- for(i=1;i<noteqcount;i++){
- for(j=1;j<dbnoteqcount;j++){
- if(mapitem.notequip[i].flag==1) break;
- if(!(dbitem.notequip[j].flag==1)){
- if(mapitem.notequip[i].nameid==dbitem.notequip[j].nameid){
- if ((mapitem.notequip[i].amount==dbitem.notequip[j].amount) && (mapitem.notequip[i].equip==dbitem.notequip[j].equip) && (mapitem.notequip[i].identify==dbitem.notequip[j].identify)
- && (mapitem.notequip[i].attribute==dbitem.notequip[j].attribute))
- { mapitem.notequip[i].flag=1;
- dbitem.notequip[j].flag=1;
- //printf("the same item : %d ; i : %d ; flag : %d\n", mapitem.notequip[i].nameid, i, mapitem.notequip[i].flag); //DEBUG-STRING
- }
- else{
- sprintf(tmp_sql,"UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d',"
- "`attribute`='%d' WHERE `%s`='%d' AND `nameid`='%d'",
- tablename, mapitem.notequip[i].amount, mapitem.notequip[i].equip, mapitem.notequip[i].identify, mapitem.notequip[i].attribute,
- selectoption, char_id, mapitem.notequip[i].nameid);
- //printf("%s",tmp_sql);
- if(mysql_query(&mysql_handle, tmp_sql))
- printf("DB server Error (UPdate `notequ %s`)- %s\n",tablename ,mysql_error(&mysql_handle));
-
- mapitem.notequip[i].flag=1;
- dbitem.notequip[j].flag=1;
- }
- }
- }
- }
- }
-
- //printf("dbnoteqcount = %d\n",dbnoteqcount);
-
- for(i=1;i<dbnoteqcount;i++){
- //printf("dbitem.notequip[i].flag = %d , dbitem.notequip[i].id = %d\n",dbitem.notequip[i].flag,dbitem.notequip[i].id);
- if(!(dbitem.notequip[i].flag==1)){
- sprintf(tmp_sql,"DELETE from `%s` where `id`='%d'", tablename, dbitem.notequip[i].id);
- //printf("%s", tmp_sql);
- if(mysql_query(&mysql_handle, tmp_sql))
- printf("DB server Error (DELETE `notequ %s`)- %s\n", tablename ,mysql_error(&mysql_handle));
- }
- }
- for(i=1;i<noteqcount;i++){
- if(!(mapitem.notequip[i].flag==1)){
- sprintf(tmp_sql,"INSERT INTO `%s`( `%s`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`)"
- " VALUES ('%d','%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
- tablename ,selectoption , char_id, mapitem.notequip[i].nameid, mapitem.notequip[i].amount, mapitem.notequip[i].equip, mapitem.notequip[i].identify, mapitem.notequip[i].refine,
- mapitem.notequip[i].attribute, mapitem.notequip[i].card[0], mapitem.notequip[i].card[1], mapitem.notequip[i].card[2], mapitem.notequip[i].card[3]);
- //printf("%s", tmp_sql);
- if(mysql_query(&mysql_handle, tmp_sql))
- printf("DB server Error (INSERT `notequ %s`)- %s\n", tablename, mysql_error(&mysql_handle));
- }
+ for(i = 0; i < count; i++) {
+ if(!mapitem[i].flag) {
+ sprintf(tmp_sql,"INSERT INTO `%s`(`%s`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3` )"
+ " VALUES ( '%d','%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d' )",
+ tablename, selectoption, char_id, mapitem[i].nameid, mapitem[i].amount, mapitem[i].equip, mapitem[i].identify, mapitem[i].refine,
+ mapitem[i].attribute, mapitem[i].card[0], mapitem[i].card[1], mapitem[i].card[2], mapitem[i].card[3]);
+ if(mysql_query(&mysql_handle, tmp_sql))
+ printf("DB server Error (INSERT `equ %s`)- %s\n", tablename, mysql_error(&mysql_handle));
}
+ }
//======================================DEBUG=================================================
@@ -747,21 +731,23 @@ int memitemdata_to_sql(struct itemtemp mapitem, int eqcount, int noteqcount, int
// printf("=================================================Data Time %s===\n", tmpstr);
// printf("=================================================================================\n");
//
- }
+
return 0;
}
-
//=====================================================================================================
int mmo_char_fromsql(int char_id, struct mmo_charstatus *p, int online){
- int i=0, n=0;
+ int i, n;
+ char *tmp_p = tmp_sql;
+ struct mmo_charstatus *cp;
+
+ cp = (struct mmo_charstatus*)numdb_search(char_db_,char_id);
+ if (cp != NULL)
+ aFree(cp);
memset(p, 0, sizeof(struct mmo_charstatus));
p->char_id = char_id;
-
- #ifdef DEBUG
- printf("Loading Char [%d]... ",char_id);
- #endif
+ printf("Loaded: ");
//`char`( `char_id`,`account_id`,`char_num`,`name`,`class`,`base_level`,`job_level`,`base_exp`,`job_exp`,`zeny`, //9
//`str`,`agi`,`vit`,`int`,`dex`,`luk`, //15
//`max_hp`,`hp`,`max_sp`,`sp`,`status_point`,`skill_point`, //21
@@ -770,15 +756,23 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus *p, int online){
//`last_map`,`last_x`,`last_y`,`save_map`,`save_x`,`save_y`)
//splite 2 parts. cause veeeery long SQL syntax
- sprintf(tmp_sql, "SELECT * FROM `%s` WHERE `char_id` = '%d'",char_db, char_id);
+ sprintf(tmp_sql, "SELECT `char_id`,`account_id`,`char_num`,`name`,`class`,`base_level`,`job_level`,`base_exp`,`job_exp`,`zeny`,"
+ "`str`,`agi`,`vit`,`int`,`dex`,`luk`, `max_hp`,`hp`,`max_sp`,`sp`,`status_point`,`skill_point` FROM `%s` WHERE `char_id` = '%d'",char_db, char_id); // TBR
- sql_query(tmp_sql,"mmo_char_fromsql");
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (select `char`)- %s\n", mysql_error(&mysql_handle));
+ }
+
+ sql_res = mysql_store_result(&mysql_handle);
- if ((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res))) {
+ if (sql_res) {
+ sql_row = mysql_fetch_row(sql_res);
+
+ p->char_id = char_id;
p->account_id = atoi(sql_row[1]);
p->char_num = atoi(sql_row[2]);
strcpy(p->name, sql_row[3]);
- p->class = atoi(sql_row[4]);
+ p->class_ = atoi(sql_row[4]);
p->base_level = atoi(sql_row[5]);
p->job_level = atoi(sql_row[6]);
p->base_exp = atoi(sql_row[7]);
@@ -796,43 +790,57 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus *p, int online){
p->sp = atoi(sql_row[19]);
p->status_point = atoi(sql_row[20]);
p->skill_point = atoi(sql_row[21]);
- p->option = atoi(sql_row[22]);
- p->karma = atoi(sql_row[23]);
- p->manner = atoi(sql_row[24]);
- p->party_id = atoi(sql_row[25]);
- p->guild_id = atoi(sql_row[26]);
- p->pet_id = atoi(sql_row[27]);
- p->hair = atoi(sql_row[28]);
- p->hair_color = atoi(sql_row[29]);
- p->clothes_color = atoi(sql_row[30]);
- p->weapon = atoi(sql_row[31]);
- p->shield = atoi(sql_row[32]);
- p->head_top = atoi(sql_row[33]);
- p->head_mid = atoi(sql_row[34]);
- p->head_bottom = atoi(sql_row[35]);
- strcpy(p->last_point.map,sql_row[36]);
- p->last_point.x = atoi(sql_row[37]);
- p->last_point.y = atoi(sql_row[38]);
- strcpy(p->save_point.map,sql_row[39]);
- p->save_point.x = atoi(sql_row[40]);
- p->save_point.y = atoi(sql_row[41]);
- p->partner_id = atoi(sql_row[42]);
+ //free mysql result.
+ mysql_free_result(sql_res);
+ } else
+ printf("char1 - failed\n"); //Error?! ERRRRRR WHAT THAT SAY!?
+ printf("(\033[1;32m%d\033[0m)\033[1;32m%s\033[0m\t[",p->char_id,p->name);
+ printf("char1 ");
+
+ sprintf(tmp_sql, "SELECT `option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`hair`,`hair_color`,"
+ "`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,"
+ "`last_map`,`last_x`,`last_y`,`save_map`,`save_x`,`save_y`, `partner_id`, `father`, `mother`, `child` FROM `%s` WHERE `char_id` = '%d'",char_db, char_id); // TBR
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (select `char2`)- %s\n", mysql_error(&mysql_handle));
+ }
+
+ sql_res = mysql_store_result(&mysql_handle);
+ if (sql_res) {
+ sql_row = mysql_fetch_row(sql_res);
+
+
+ p->option = atoi(sql_row[0]); p->karma = atoi(sql_row[1]); p->manner = atoi(sql_row[2]);
+ p->party_id = atoi(sql_row[3]); p->guild_id = atoi(sql_row[4]); p->pet_id = atoi(sql_row[5]);
+
+ p->hair = atoi(sql_row[6]); p->hair_color = atoi(sql_row[7]); p->clothes_color = atoi(sql_row[8]);
+ p->weapon = atoi(sql_row[9]); p->shield = atoi(sql_row[10]);
+ p->head_top = atoi(sql_row[11]); p->head_mid = atoi(sql_row[12]); p->head_bottom = atoi(sql_row[13]);
+ strcpy(p->last_point.map,sql_row[14]); p->last_point.x = atoi(sql_row[15]); p->last_point.y = atoi(sql_row[16]);
+ strcpy(p->save_point.map,sql_row[17]); p->save_point.x = atoi(sql_row[18]); p->save_point.y = atoi(sql_row[19]);
+ p->partner_id = atoi(sql_row[20]); p->father = atoi(sql_row[21]); p->mother = atoi(sql_row[22]); p->child = atoi(sql_row[23]);
//free mysql result.
mysql_free_result(sql_res);
-#ifdef DEBUG
- printf("Loading of char [%d] Completed!\n",char_id);
- } else {
- printf("Loading of char [%d] FAILED!\n",char_id); //Error?! ERRRRRR WHAT THAT SAY!?
-#endif
- }
+ } else
+ printf("char2 - failed\n"); //Error?! ERRRRRR WHAT THAT SAY!?
+
+ if (p->last_point.x == 0 || p->last_point.y == 0 || p->last_point.map[0] == '\0')
+ memcpy(&p->last_point, &start_point, sizeof(start_point));
+
+ if (p->save_point.x == 0 || p->save_point.y == 0 || p->save_point.map[0] == '\0')
+ memcpy(&p->save_point, &start_point, sizeof(start_point));
+
+ printf("char2 ");
//read memo data
//`memo` (`memo_id`,`char_id`,`map`,`x`,`y`)
- sprintf(tmp_sql, "SELECT `map`,`x`,`y` FROM `%s` WHERE `char_id`='%d'",memo_db, char_id);
- sql_query(tmp_sql,"mmo_char_fromsql");
+ sprintf(tmp_sql, "SELECT `map`,`x`,`y` FROM `%s` WHERE `char_id`='%d'",memo_db, char_id); // TBR
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (select `memo`)- %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle);
- if ((sql_res = mysql_store_result(&mysql_handle))) {
+ if (sql_res) {
for(i=0;(sql_row = mysql_fetch_row(sql_res));i++){
strcpy (p->memo_point[i].map,sql_row[0]);
p->memo_point[i].x=atoi(sql_row[1]);
@@ -841,83 +849,87 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus *p, int online){
}
mysql_free_result(sql_res);
}
-#ifdef DEBUG
- printf("Char [%s] - Memo Loaded\n",p->name);
-#endif
+ printf("memo ");
//read inventory
//`inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`)
- sprintf(tmp_sql, "SELECT * FROM `%s` WHERE `char_id`='%d'",inventory_db, char_id);
- sql_query(tmp_sql,"mmo_char_fromsql");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
+ sprintf(tmp_sql, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`"
+ "FROM `%s` WHERE `char_id`='%d'",inventory_db, char_id); // TBR
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (select `inventory`)- %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle);
+ if (sql_res) {
for(i=0;(sql_row = mysql_fetch_row(sql_res));i++){
- p->inventory[i].id = atoi(sql_row[1]);
- p->inventory[i].nameid = atoi(sql_row[2]);
- p->inventory[i].amount = atoi(sql_row[3]);
- p->inventory[i].equip = atoi(sql_row[4]);
- p->inventory[i].identify = atoi(sql_row[5]);
- p->inventory[i].refine = atoi(sql_row[6]);
- p->inventory[i].attribute = atoi(sql_row[7]);
- p->inventory[i].card[0] = atoi(sql_row[8]);
- p->inventory[i].card[1] = atoi(sql_row[9]);
- p->inventory[i].card[2] = atoi(sql_row[10]);
- p->inventory[i].card[3] = atoi(sql_row[11]);
+ p->inventory[i].id = atoi(sql_row[0]);
+ p->inventory[i].nameid = atoi(sql_row[1]);
+ p->inventory[i].amount = atoi(sql_row[2]);
+ p->inventory[i].equip = atoi(sql_row[3]);
+ p->inventory[i].identify = atoi(sql_row[4]);
+ p->inventory[i].refine = atoi(sql_row[5]);
+ p->inventory[i].attribute = atoi(sql_row[6]);
+ p->inventory[i].card[0] = atoi(sql_row[7]);
+ p->inventory[i].card[1] = atoi(sql_row[8]);
+ p->inventory[i].card[2] = atoi(sql_row[9]);
+ p->inventory[i].card[3] = atoi(sql_row[10]);
}
mysql_free_result(sql_res);
}
-#ifdef DEBUG
- printf("Char [%s] - Inventory Loaded\n",p->name);
-#endif
+ printf("inventory ");
+
//read cart.
//`cart_inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`)
- sprintf(tmp_sql, "SELECT * FROM `%s` WHERE `char_id`='%d'",cart_db, char_id);
- sql_query(tmp_sql,"mmo_char_fromsql");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
+ sprintf(tmp_sql, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`"
+ "FROM `%s` WHERE `char_id`='%d'",cart_db, char_id); // TBR
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (select `cart_inventory`)- %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle);
+ if (sql_res) {
for(i=0;(sql_row = mysql_fetch_row(sql_res));i++){
- p->cart[i].id = atoi(sql_row[1]);
- p->cart[i].nameid = atoi(sql_row[2]);
- p->cart[i].amount = atoi(sql_row[3]);
- p->cart[i].equip = atoi(sql_row[4]);
- p->cart[i].identify = atoi(sql_row[5]);
- p->cart[i].refine = atoi(sql_row[6]);
- p->cart[i].attribute = atoi(sql_row[7]);
- p->cart[i].card[0] = atoi(sql_row[8]);
- p->cart[i].card[1] = atoi(sql_row[9]);
- p->cart[i].card[2] = atoi(sql_row[10]);
- p->cart[i].card[3] = atoi(sql_row[11]);
+ p->cart[i].id = atoi(sql_row[0]);
+ p->cart[i].nameid = atoi(sql_row[1]);
+ p->cart[i].amount = atoi(sql_row[2]);
+ p->cart[i].equip = atoi(sql_row[3]);
+ p->cart[i].identify = atoi(sql_row[4]);
+ p->cart[i].refine = atoi(sql_row[5]);
+ p->cart[i].attribute = atoi(sql_row[6]);
+ p->cart[i].card[0] = atoi(sql_row[7]);
+ p->cart[i].card[1] = atoi(sql_row[8]);
+ p->cart[i].card[2] = atoi(sql_row[9]);
+ p->cart[i].card[3] = atoi(sql_row[10]);
}
mysql_free_result(sql_res);
}
-#ifdef DEBUG
- printf("Char [%s] - Cart Inventory Loaded\n",p->name);
-#endif
+ printf("cart ");
//read skill
//`skill` (`char_id`, `id`, `lv`)
- sprintf(tmp_sql, "SELECT `id`, `lv` FROM `%s` WHERE `char_id`='%d'",skill_db, char_id);
- sql_query(tmp_sql,"mmo_char_fromsql");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
+ sprintf(tmp_sql, "SELECT `id`, `lv` FROM `%s` WHERE `char_id`='%d'",skill_db, char_id); // TBR
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (select `skill`)- %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle);
+ if (sql_res) {
for(i=0;(sql_row = mysql_fetch_row(sql_res));i++){
- n = atoi(sql_row[0]);
- p->skill[n].id = n;
+ n = atoi(sql_row[0]);
+ p->skill[n].id = n; //memory!? shit!.
p->skill[n].lv = atoi(sql_row[1]);
}
mysql_free_result(sql_res);
}
-#ifdef DEBUG
- printf("Char [%s] - Skills Loaded\n",p->name);
-#endif
+ printf("skill ");
//global_reg
//`global_reg_value` (`char_id`, `str`, `value`)
- sprintf(tmp_sql, "SELECT `str`, `value` FROM `%s` WHERE `type`=3 AND `char_id`='%d'",reg_db, char_id);
- sql_query(tmp_sql,"mmo_char_fromsql");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
+ sprintf(tmp_sql, "SELECT `str`, `value` FROM `%s` WHERE `type`=3 AND `char_id`='%d'",reg_db, char_id); // TBR
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (select `global_reg_value`)- %s\n", mysql_error(&mysql_handle));
+ }
+ i = 0;
+ sql_res = mysql_store_result(&mysql_handle);
+ if (sql_res) {
for(i=0;(sql_row = mysql_fetch_row(sql_res));i++){
strcpy (p->global_reg[i].str, sql_row[0]);
p->global_reg[i].value = atoi (sql_row[1]);
@@ -925,76 +937,152 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus *p, int online){
mysql_free_result(sql_res);
}
p->global_reg_num=i;
-#ifdef DEBUG
- printf("Char [%s] - Global Reg Loaded\n",p->name);
-#endif
+
+ //Friends List Load
+
+ for(i=0;i<20;i++) {
+ p->friend_id[i] = 0;
+ p->friend_name[i][0] = '\0';
+ }
+
+ tmp_p += sprintf(tmp_p, "SELECT `id`, `account_id`");
+
+ for(i=0;i<20;i++)
+ tmp_p += sprintf(tmp_p, ", `friend_id%d`, `name%d`", i, i);
+
+ tmp_p += sprintf(tmp_p, " FROM `%s` WHERE `account_id`='%d' ", friend_db, char_id); // TBR
+
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (select `friends list`)- %s\n", mysql_error(&mysql_handle));
+ }
+
+ sql_res = mysql_store_result(&mysql_handle);
+ sql_row = mysql_fetch_row(sql_res);
+
+ i=mysql_num_rows(sql_res);
+
+ // debugg
+ //printf("mysql: %d\n",i);
+
+ // Create an entry for the character if it doesnt already have one
+ if(!i) {
+
+ insert_friends(char_id);
+
+ } else {
+
+ if (sql_res) {
+ for(i=0;i<20;i++) {
+ p->friend_id[i] = atoi(sql_row[i*2 +2]);
+ sprintf(p->friend_name[i], "%s", sql_row[i*2 +3]);
+ }
+ mysql_free_result(sql_res);
+ }
+ }
+
+ printf("friends ");
+
+ //-- end friends list load --
if (online) {
- sprintf(tmp_sql, "UPDATE `%s` SET `online`='%d' WHERE `char_id`='%d'",char_db,online,char_id);
- sql_query(tmp_sql,"mmo_char_fromsql");
+ set_char_online(char_id,p->account_id);
}
-#ifdef DEBUG
- printf("Char [%d][%s] - Loading Complete\n",char_id,p->name);
-#endif
+ printf("char data load success]\n"); //ok. all data load successfuly!
+
+ cp = (struct mmo_charstatus *) aMalloc(sizeof(struct mmo_charstatus));
+ memcpy(cp, p, sizeof(struct mmo_charstatus));
+ numdb_insert(char_db_, char_id,cp);
return 1;
}
//==========================================================================================================
int mmo_char_sql_init(void) {
- int i=0;
- #ifdef DEBUG
- int cid=0;
- #endif
+ int charcount;
+
+ char_db_=numdb_init();
+ printf("init start.......\n");
// memory initialize
// no need to set twice size in this routine. but some cause segmentation error. :P
- #ifdef DEBUG
- printf("Initializing char memory...(%d byte)\n",sizeof(struct mmo_charstatus)*2);
- #endif
-
+ printf("initializing char memory...(%d byte)\n",sizeof(struct mmo_charstatus)*2);
CREATE(char_dat, struct mmo_charstatus, 2);
+
memset(char_dat, 0, sizeof(struct mmo_charstatus)*2);
+/* Initialized in inter.c already [Wizputer]
+ // DB connection initialized
+ // for char-server session only
+ mysql_init(&mysql_handle);
+ printf("Connect DB server....(char server)\n");
+ if(!mysql_real_connect(&mysql_handle, char_server_ip, char_server_id, char_server_pw, char_server_db ,char_server_port, (char *)NULL, 0)) {
+ // SQL connection pointer check
+ printf("%s\n",mysql_error(&mysql_handle));
+ exit(1);
+ } else {
+ printf("connect success! (char server)\n");
+ }
+*/ /* Removed .. not needed now :P
sprintf(tmp_sql , "SELECT count(*) FROM `%s`", char_db);
- sql_query(tmp_sql,"mmo_char_sql_init");
-
- if((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res))) {
- i = atoi (sql_row[0]);
- #ifdef DEBUG
- printf("Total number of chars in DB [%d]\n",i);
- #endif
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
}
+ sql_res = mysql_store_result(&mysql_handle) ;
+ sql_row = mysql_fetch_row(sql_res);
+ printf("total char data -> '%s'.......\n",sql_row[0]);
+ i = atoi (sql_row[0]);
+ mysql_free_result(sql_res);
- mysql_free_result(sql_res);
-
- // Because it's no longer needed, I made it debug. Some people may still want to know the highest
- // char_id. It has no functional purpose though. [Ajarn]
- #ifdef DEBUG
- if (i != 0) {
+ if (i !=0) {
sprintf(tmp_sql , "SELECT max(`char_id`) FROM `%s`", char_db);
- sql_query(tmp_sql,"mmo_char_sql_init");
-
- if((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res)))
- cid = atoi (sql_row[0]);
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle) ;
+ sql_row = mysql_fetch_row(sql_res);
+ char_id_count = atoi (sql_row[0]);
mysql_free_result(sql_res);
- }
- printf("Highest Char ID [%d]\n",cid);
- #endif
+ } else
+ printf("set char_id_count: %d.......\n",char_id_count);
+ */
+ sprintf(tmp_sql, "SELECT `char_id` FROM `%s`", char_db);
+ if(mysql_query(&mysql_handle, tmp_sql)){
+ //fail :(
+ printf("SQL Error (in select the charid .. (all)): %s", mysql_error(&mysql_handle));
+ }else{
+ sql_res = mysql_store_result(&mysql_handle);
+ if(sql_res){
+ charcount = mysql_num_rows(sql_res);
+ printf("total char data -> '%d'.......\n", charcount);
+ mysql_free_result(sql_res);
+ }else{
+ printf("total char data -> '0'.......\n");
+ }
+ }
+
+ if(char_per_account == 0){
+ printf("Chars per Account: 'Unlimited'.......\n");
+ }else{
+ printf("Chars per Account: '%d'.......\n", char_per_account);
+ }
- if (i == 0) {
- // If there is no characters in the SQL DB, make sure the starting id will be MIN_CHAR_ID
- // Remove once main.sql has this to begin with and it's a standard to have it be this way
- // (thus saving a check) [Ajarn]
- sprintf(tmp_sql , "ALTER TABLE `%s` AUTO_INCREMENT = %d", char_db, MIN_CHAR_ID-1);
- sql_query(tmp_sql,"mmo_char_sql_init");
- }
+ //sprintf(tmp_sql , "REPLACE INTO `%s` SET `online`=0", char_db); //OLD QUERY ! BUGGED
+ sprintf(tmp_sql, "UPDATE `%s` SET `online` = '0'", char_db);//fixed the on start 0 entrys!
+ if (mysql_query(&mysql_handle, tmp_sql))
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ //sprintf(tmp_sql , "REPLACE INTO `%s` SET `online`=0", guild_member_db); //OLD QUERY ! BUGGED
+ sprintf(tmp_sql, "UPDATE `%s` SET `online` = '0'", guild_member_db);//fixed the 0 entrys in start ..
+ if (mysql_query(&mysql_handle, tmp_sql))
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
- #ifdef DEBUG
- printf("Init finsihed\n");
- #endif
+ //sprintf(tmp_sql , "REPLACE INTO `%s` SET `connect_member`=0", guild_db); //OLD QUERY BUGGED!
+ sprintf(tmp_sql, "UPDATE `%s` SET `connect_member` = '0'", guild_db);//fixed the 0 entrys in start.....
+ if (mysql_query(&mysql_handle, tmp_sql))
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+
+ printf("init end.......\n");
return 0;
}
@@ -1004,105 +1092,246 @@ int mmo_char_sql_init(void) {
int make_new_char_sql(int fd, unsigned char *dat) {
struct char_session_data *sd;
char t_name[100];
- int i, cid;
-
- //aphostropy error check! - fixed!
- jstrescapecpy(t_name, dat);
-
- #ifdef DEBUG
- printf("Making new char [%s]\n",dat);
- #endif
+ int i, char_id, temp;
- sd = session[fd]->session_data;
+ //aphostropy error check! - fixed!
+ jstrescapecpy(t_name, (char*)dat);
+
+ sd = (struct char_session_data*)session[fd]->session_data;
+
+ printf("[CHAR] Add - ");
+
+ //check for charcount (maxchars) :)
+ if(char_per_account != 0){
+ sprintf(tmp_sql, "SELECT `account_id` FROM `%s` WHERE `account_id` = '%d'", char_db, sd->account_id);
+ if(mysql_query(&mysql_handle, tmp_sql)){
+ printf("fail, SQL Error: %s !!FAIL!!\n", tmp_sql);
+ }
+ sql_res = mysql_store_result(&mysql_handle);
+ if(sql_res){
+ //ok
+ temp = mysql_num_rows(sql_res);
+ if(temp >= char_per_account){
+ //hehe .. limit exceeded :P
+ printf("fail (aid: %d), charlimit exceeded.\n", sd->account_id);
+ mysql_free_result(sql_res);
+ return -2;
+ }
+ mysql_free_result(sql_res);
+ }
+ }
+
// Check Authorised letters/symbols in the name of the character
if (char_name_option == 1) { // only letters/symbols in char_name_letters are authorised
- for (i = 0; i < strlen(dat); i++)
+ for (i = 0; i < strlen((const char*)dat); i++)
if (strchr(char_name_letters, dat[i]) == NULL)
- return -1;
+ return -2;
} else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
- for (i = 0; i < strlen(dat); i++)
+ for (i = 0; i < strlen((const char*)dat); i++)
if (strchr(char_name_letters, dat[i]) != NULL)
- return -1;
+ return -2;
} // else, all letters/symbols are authorised (except control char removed before)
+
//check stat error
if ((dat[24]+dat[25]+dat[26]+dat[27]+dat[28]+dat[29]!=5*6 ) ||
- (dat[30] >= 9) || (dat[33] <= 0) || (dat[33] >= 20) ||
+ (dat[30] >= 9) ||
+ (dat[33] <= 0) || (dat[33] >= 20) ||
(dat[31] >= 9)) {
// check individual stat value
for(i = 24; i <= 29; i++) {
if (dat[i] < 1 || dat[i] > 9) {
- return -1;
+ printf("fail (aid: %d), stats error(bot cheat?!)\n", sd->account_id);
+ return -2;
}
}
+ if (log_char) {
+ // char.log to charlog
+ sprintf(tmp_sql,"INSERT INTO `%s` (`time`, `char_msg`,`account_id`,`char_num`,`name`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`hair`,`hair_color`)"
+ "VALUES (NOW(), '%s', '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
+ charlog_db,"make new char error", sd->account_id, dat[30], dat, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29], dat[33], dat[31]);
+ //query
+ mysql_query(&mysql_handle, tmp_sql);
+ }
+ //printf("make new char error %d-%d %s %d, %d, %d, %d, %d, %d %d, %d" RETCODE,
+ // fd, dat[30], dat, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29], dat[33], dat[31]);
+
+ printf("fail (aid: %d), stats error(bot cheat?!)\n", sd->account_id);
+ return -2;
+ }
+
+ if (log_char) {
// char.log to charlog
- sprintf(tmp_sql,"INSERT DELAYED INTO `%s` (`time`, `char_msg`,`account_id`,`char_num`,`name`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`hair`,`hair_color`)"
+ sprintf(tmp_sql,"INSERT INTO `%s`(`time`, `char_msg`,`account_id`,`char_num`,`name`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`hair`,`hair_color`)"
"VALUES (NOW(), '%s', '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
- charlog_db,"make new char error", sd->account_id, dat[30], dat, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29], dat[33], dat[31]);
+ charlog_db,"make new char", sd->account_id, dat[30], dat, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29], dat[33], dat[31]);
//query
- sql_query(tmp_sql,"amke_new_char_sql");
-
- #ifdef DEBUG
- printf("Make new char error %d-%d %s %d, %d, %d, %d, %d, %d %d, %d" RETCODE,
- fd, dat[30], dat, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29], dat[33], dat[31]);
- #endif
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("fail(log error), SQL error: %s\n", mysql_error(&mysql_handle));
+ }
+ }
+ //printf("make new char %d-%d %s %d, %d, %d, %d, %d, %d - %d, %d" RETCODE,
+ // fd, dat[30], dat, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29], dat[33], dat[31]);
+ //Check Name (already in use?)
+ sprintf(tmp_sql, "SELECT `name` FROM `%s` WHERE `name` = '%s'",char_db, t_name);
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("fail (namecheck!), SQL error: %s\n", mysql_error(&mysql_handle));
+ return -2;
+ }
+ sql_res = mysql_store_result(&mysql_handle);
+ if(sql_res){
+ temp = mysql_num_rows(sql_res);
+
+ if (temp > 0) {
+ mysql_free_result(sql_res);
+ printf("fail, charname already in use\n");
return -1;
+ }
+ mysql_free_result(sql_res);
}
- // char.log to charlog
- sprintf(tmp_sql,"INSERT DELAYED INTO `%s`(`time`, `char_msg`,`account_id`,`char_num`,`name`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`hair`,`hair_color`)"
- "VALUES (NOW(), '%s', '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
- charlog_db,"make new char", sd->account_id, dat[30], dat, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29], dat[33], dat[31]);
- //query
- sql_query(tmp_sql,"make_new_char_sql");
-
- #ifdef DEBUG
- printf("make new char %d-%d %s %d, %d, %d, %d, %d, %d - %d, %d" RETCODE,
- fd, dat[30], dat, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29], dat[33], dat[31]);
- #endif
-
// check char slot.
- sprintf(tmp_sql, "SELECT count(*) FROM `%s` WHERE `account_id` = '%d' AND `char_num` = '%d'",char_db, sd->account_id, dat[30]);
- sql_query(tmp_sql,"make_new_char_sql");
-
- if((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res))) {
- if (atoi(sql_row[0]) > 0) {
- mysql_free_result(sql_res);
- return -1;
- } else
- mysql_free_result(sql_res);
+ sprintf(tmp_sql, "SELECT `account_id`, `char_num` FROM `%s` WHERE `account_id` = '%d' AND `char_num` = '%d'",char_db, sd->account_id, dat[30]);
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("fail (charslot check), SQL error: %s\n", mysql_error(&mysql_handle));
}
+ sql_res = mysql_store_result(&mysql_handle);
+
+ if(sql_res){
+ temp = mysql_num_rows(sql_res);
+ if (temp > 0) {
+ mysql_free_result(sql_res);
+ printf("fail (aid: %d, slot: %d), slot already in use\n", sd->account_id, dat[30]);
+ return -2;
+ }
+ mysql_free_result(sql_res);
+ }
+
//char_id_count++;
- // make new char.
- sprintf(tmp_sql,"INSERT INTO `%s` (`account_id`,`char_num`,`name`,`zeny`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,"
- "`max_hp`,`hp`,`max_sp`,`sp`,`hair`,`hair_color`,`last_map`,`last_x`,`last_y`,`save_map`,`save_x`,`save_y`)"
- " VALUES ('%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d','%d', '%d','%d', '%d','%s','%d','%d','%s','%d','%d')",
- char_db, sd->account_id , dat[30] , t_name, start_zeny, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29],
- (40 * (100 + dat[26])/100) , (40 * (100 + dat[26])/100 ), (11 * (100 + dat[27])/100), (11 * (100 + dat[27])/100), dat[33], dat[31],
- start_point.map,start_point.x,start_point.y, start_point.map,start_point.x,start_point.y);
+ // make new char.
+ /*
+ sprintf(tmp_sql,"INSERT INTO `%s` (`char_id`,`account_id`,`char_num`,`name`,`zeny`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`max_hp`,`hp`,`max_sp`,`sp`,`hair`,`hair_color`)"
+ " VALUES ('%d', '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d','%d', '%d','%d', '%d')",
+ char_db, char_id_count, sd->account_id , dat[30] , t_name, start_zeny, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29],
+ (40 * (100 + dat[26])/100) , (40 * (100 + dat[26])/100 ), (11 * (100 + dat[27])/100), (11 * (100 + dat[27])/100), dat[33], dat[31]);
if (mysql_query(&mysql_handle, tmp_sql)) {
- printf("DB server Error (insert new char into `char`)- %s\n", mysql_error(&mysql_handle));
- return -1;
+ printf("DB server Error (insert `char`)- %s\n", mysql_error(&mysql_handle));
}
- cid = mysql_last_insert_id(sql_res);
-
//`inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`)
- sprintf(tmp_sql,"INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `equip`, `identify`) VALUES ('%d', '%d', '%d', '%d', '%d'),('%d', '%d', '%d', '%d', '%d')",
- inventory_db, cid, 1201,1,0x02,1,cid,2301,1,0x10,1); //add Knife and Cotton Shirt
- sql_query(tmp_sql,"make_new_char_sql");
+ sprintf(tmp_sql,"INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `equip`, `identify`) VALUES ('%d', '%d', '%d', '%d', '%d')",
+ inventory_db, char_id_count, 1201,1,0x02,1); //add Knife
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (insert `inventory`)- %s\n", mysql_error(&mysql_handle));
+ }
+
+ sprintf(tmp_sql,"INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `equip`, `identify`) VALUES ('%d', '%d', '%d', '%d', '%d')",
+ inventory_db, char_id_count, 2301,1,0x10,1); //add Cotton Shirt
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (insert `inventory`)- %s\n", mysql_error(&mysql_handle));
+ }
+ // respawn map and start point set
+ sprintf(tmp_sql,"UPDATE `%s` SET `last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d' WHERE `char_id` = '%d'",
+ char_db, start_point.map,start_point.x,start_point.y, start_point.map,start_point.x,start_point.y, char_id_count);
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (update `char`)- %s\n", mysql_error(&mysql_handle));
+ }
+
+
+ // Insert friends list
+ insert_friends(char_id_count);
+ */
+
+ //New Querys [Sirius]
+ //Insert the char to the 'chardb' ^^
+ sprintf(tmp_sql, "INSERT INTO `%s` (`account_id`, `char_num`, `name`, `zeny`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `max_hp`, `hp`, `max_sp`, `sp`, `hair`, `hair_color`, `last_map`, `last_x`, `last_y`, `save_map`, `save_x`, `save_y`) VALUES ('%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d','%d', '%d','%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d')", char_db, sd->account_id , dat[30] , t_name, start_zeny, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29], (40 * (100 + dat[26])/100) , (40 * (100 + dat[26])/100 ), (11 * (100 + dat[27])/100), (11 * (100 + dat[27])/100), dat[33], dat[31], start_point.map, start_point.x, start_point.y, start_point.map, start_point.x, start_point.y);
+ if(mysql_query(&mysql_handle, tmp_sql)){
+ printf("failed (insert in chardb), SQL error: %s\n", mysql_error(&mysql_handle));
+ return -2; //No, stop the procedure!
+ }
+
+ //Now we need the charid from sql!
+ sprintf(tmp_sql, "SELECT `char_id` FROM `%s` WHERE `account_id` = '%d' AND `char_num` = '%d' AND `name` = '%s'", char_db, sd->account_id , dat[30] , t_name);
+ if(mysql_query(&mysql_handle, tmp_sql)){
+ printf("failed (get char_id), SQL error: %s\n", mysql_error(&mysql_handle));
+ //delete the char ..(no trash in DB!)
+ sprintf(tmp_sql, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `char_num` = '%d' AND `name` = '%s'", char_db, sd->account_id, dat[30], t_name);
+ mysql_query(&mysql_handle, tmp_sql);
+ return -2; //XD end of the (World? :P) .. charcreate (denied)
+ }else{
+ //query ok -> get the data!
+ sql_res = mysql_store_result(&mysql_handle);
+ if(sql_res){
+ sql_row = mysql_fetch_row(sql_res);
+ char_id = atoi(sql_row[0]); //char id :)
+ mysql_free_result(sql_res);
+ if(char_id <= 0){
+ printf("failed (get char id..) CHARID wrong!\n");
+ sprintf(tmp_sql, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `char_num` = '%d' AND `name` = '%s'", char_db, sd->account_id, dat[30], t_name);
+ mysql_query(&mysql_handle, tmp_sql);
+ return -2; //charcreate denied ..
+ }
+ }else{
+ //prevent to crash (if its false, and we want to free -> segfault :)
+ printf("failed (get char id.. res), SQL error: %s\n", mysql_error(&mysql_handle));
+ sprintf(tmp_sql, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `char_num` = '%d' AND `name` = '%s'", char_db, sd->account_id, dat[30], t_name);
+ mysql_query(&mysql_handle, tmp_sql);
+ return -2; //end ...... -> charcreate failed :)
+ }
+ }
+
+ //Give the char the default items
+ //knife
+ sprintf(tmp_sql,"INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `equip`, `identify`) VALUES ('%d', '%d', '%d', '%d', '%d')", inventory_db, char_id, 1201,1,0x02,1); //add Knife
+ if (mysql_query(&mysql_handle, tmp_sql)){
+ printf("fail (insert in inventory the 'knife'), SQL error: %s\n", mysql_error(&mysql_handle));
+ sprintf(tmp_sql, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `char_num` = '%d' AND `name` = '%s'", char_db, sd->account_id, dat[30], t_name);
+ mysql_query(&mysql_handle, tmp_sql);
+ return -2;//end XD
+ }
+ //cotton shirt
+ sprintf(tmp_sql,"INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `equip`, `identify`) VALUES ('%d', '%d', '%d', '%d', '%d')", inventory_db, char_id, 2301,1,0x10,1); //add Cotton Shirt
+ if (mysql_query(&mysql_handle, tmp_sql)){
+ printf("fail (insert in inventroxy the 'cotton shirt'), SQL error: %s\n", mysql_error(&mysql_handle));
+ sprintf(tmp_sql, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `char_num` = '%d' AND `name` = '%s'", char_db, sd->account_id, dat[30], t_name);
+ mysql_query(&mysql_handle, tmp_sql);
+ sprintf(tmp_sql, "DELETE FROM `%s` WHERE `char_id` = '%d'", inventory_db, char_id);
+ mysql_query(&mysql_handle, tmp_sql);
+ return -2; //end....
+ }
+
+ if(!insert_friends(char_id)){
+ printf("fail (friendlist entrys..)\n");
+ sprintf(tmp_sql, "DELETE FROM `%s` WHERE `char_id` = '%d'", char_db, char_id);
+ mysql_query(&mysql_handle, tmp_sql);
+ sprintf(tmp_sql, "DELETE FROM `%s` WHERE `char_id` = '%d'", inventory_db, char_id);
+ mysql_query(&mysql_handle, tmp_sql);
+ return -2; //end.. charcreate failed
+ }
+
+ //printf("making new char success - id:(\033[1;32m%d\033[0m\tname:\033[1;32%s\033[0m\n", char_id, t_name);
+ printf("success, aid: %d, cid: %d, slot: %d, name: %s\n", sd->account_id, char_id, dat[30], t_name);
+ return char_id;
+}
+
+//==========================================================================================================
+
+void mmo_char_sync(void){
+ printf("mmo_char_sync() - nothing to do\n");
+}
- #ifdef DEBUG
- printf("Make new char success - id:(\033[1;32m%d\033[0m\tname:\033[1;32%s\033[0m\n", cid, t_name);
- #endif
+// to do
+///////////////////////////
- return cid;
+int mmo_char_sync_timer(int tid, unsigned int tick, int id, int data) {
+ printf("mmo_char_sync_timer() tic - no works to do\n");
+ return 0;
}
int count_users(void) {
@@ -1110,7 +1339,7 @@ int count_users(void) {
if (login_fd > 0 && session[login_fd]){
users = 0;
- for(i = 0; i < MAX_MAP_SERVERS && i < servers_connected; i++) {
+ for(i = 0; i < MAX_MAP_SERVERS; i++) {
if (server_fd[i] >= 0) {
users += server[i].users;
}
@@ -1120,52 +1349,40 @@ int count_users(void) {
return 0;
}
-int send_users_tologin(int tid, unsigned int tick, int id, int data) {
- int users = count_users();
- char buf[16];
-
- if (login_fd > 0 && session[login_fd]) {
- // send number of user to login server
- WFIFOW(login_fd,0) = 0x2714;
- WFIFOL(login_fd,2) = users;
- WFIFOSET(login_fd,6);
- }
- // send number of players to all map-servers
- WBUFW(buf,0) = 0x2b00;
- WBUFL(buf,2) = users;
- mapif_sendall(buf, 6);
-
- return 0;
-}
-
-
-
int mmo_char_send006b(int fd, struct char_session_data *sd) {
int i, j, found_num = 0;
struct mmo_charstatus *p = NULL;
-
+// hehe. commented other. anyway there's no need to use older version.
+// if use older packet version just uncomment that!
+//#ifdef NEW_006b
const int offset = 24;
+//#else
+// int offset = 4;
+//#endif
- #ifdef DEBUG
- printf("Send Chars (account:%d)\n",sd->account_id);
- #endif
+ printf("mmo_char_send006b start.. (account:%d)\n",sd->account_id);
+// printf("offset -> %d...\n",offset);
+
+ set_char_online(99,sd->account_id);
//search char.
sprintf(tmp_sql, "SELECT `char_id` FROM `%s` WHERE `account_id` = '%d'",char_db, sd->account_id);
- sql_query(tmp_sql,"mmo_char_send006b");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle);
+ if (sql_res) {
found_num = mysql_num_rows(sql_res);
-
- #ifdef DEBUG
printf("number of chars: %d\n", found_num);
- #endif
-
- for(i=0;(sql_row = mysql_fetch_row(sql_res));i++)
+ i = 0;
+ while((sql_row = mysql_fetch_row(sql_res))) {
sd->found_char[i] = atoi(sql_row[0]);
+ i++;
+ }
+ mysql_free_result(sql_res);
}
- mysql_free_result(sql_res);
+// printf("char fetching end (total: %d)....\n", found_num);
for(i = found_num; i < 9; i++)
sd->found_char[i] = -1;
@@ -1174,9 +1391,7 @@ int mmo_char_send006b(int fd, struct char_session_data *sd) {
WFIFOW(fd, 0) = 0x6b;
WFIFOW(fd, 2) = offset + found_num * 106;
- #ifdef DEBUG
printf("(\033[1;13m%d\033[0m) Request Char Data:\n",sd->account_id);
- #endif
for(i = 0; i < found_num; i++) {
mmo_char_fromsql(sd->found_char[i], char_dat, 0);
@@ -1204,9 +1419,15 @@ int mmo_char_send006b(int fd, struct char_session_data *sd) {
WFIFOW(fd,j+46) = (p->sp > 0x7fff) ? 0x7fff : p->sp;
WFIFOW(fd,j+48) = (p->max_sp > 0x7fff) ? 0x7fff : p->max_sp;
WFIFOW(fd,j+50) = DEFAULT_WALK_SPEED; // p->speed;
- WFIFOW(fd,j+52) = p->class;
+ WFIFOW(fd,j+52) = p->class_;
WFIFOW(fd,j+54) = p->hair;
- WFIFOW(fd,j+56) = p->weapon;
+
+ // pecopeco knights/crusaders crash fix
+ if (p->class_ == 13 || p->class_ == 21 ||
+ p->class_ == 4014 || p->class_ == 4022)
+ WFIFOW(fd,j+56) = 0;
+ else WFIFOW(fd,j+56) = p->weapon;
+
WFIFOW(fd,j+58) = p->base_level;
WFIFOW(fd,j+60) = p->skill_point;
WFIFOW(fd,j+62) = p->head_bottom;
@@ -1228,246 +1449,22 @@ int mmo_char_send006b(int fd, struct char_session_data *sd) {
}
WFIFOSET(fd,WFIFOW(fd,2));
-
- #ifdef DEBUG
- printf("Sent [%d] Chars to [%d]\n",found_num,sd->account_id);
- #endif
-
+// printf("mmo_char_send006b end..\n");
return 0;
}
-int reply_login_request(int fd, int len) {
- if (len < 3)
- return -1;
-
- if (RFIFOB(fd, 2)) {
- printf("Can not connect to login-server.\n");
- printf("The server communication passwords (default s1/p1) is probably invalid.\n");
- printf("Also, please make sure your login db has the username/password present and the sex of the account is S.\n");
- printf("If you changed the communication passwords, change them back at map_athena.conf and char_athena.conf\n");
- return -1;
- }else {
- printf("Connected to login-server (connection #%d).\n", fd);
- // if no map-server already connected, display a message...
- if(!servers_connected)
- printf("Awaiting maps from map-server.\n");
-
- // send USER COUNT PING to login server.
- #ifdef DEBUG
- printf("Add timer: (send_users_tologin)\n");
- #endif
-
- user_count_timer = add_timer_interval(gettick() + 10, send_users_tologin, 0, 0, 5 * 1000);
- }
-
- RFIFOSKIP(fd, 3);
-
- return 0;
-}
-
-int send_chars(int fd, int len) {
- if(len<51)
- return -1;
-
- int i;
- struct char_session_data *sd;
-
- for(i = 0; i < fd_max; i++) {
- if (session[i] && (sd = session[i]->session_data) && sd->account_id == RFIFOL(fd,2)) {
- if (RFIFOB(fd,6) != 0) {
- WFIFOW(i,0) = 0x6c;
- WFIFOB(i,2) = 0x42;
- WFIFOSET(i,3);
- } else if (max_connect_user == 0 || count_users() < max_connect_user) {
- sd->connect_until_time = (time_t)RFIFOL(fd,47);
- // send characters to player
- mmo_char_send006b(i, sd);
- } else {
- // refuse connection: too much online players
- WFIFOW(i,0) = 0x6c;
- WFIFOW(i,2) = 0;
- WFIFOSET(i,3);
- }
- }
- }
- RFIFOSKIP(fd,51);
-
- return 0;
-}
-
-int connect_until_reply(int fd, int len) {
- if (len < 50)
- return -1;
-
- int i;
- struct char_session_data *sd;
-
- for(i = 0; i < fd_max; i++) {
- if (session[i] && (sd = session[i]->session_data)) {
- if (sd->account_id == RFIFOL(fd,2)) {
- sd->connect_until_time = (time_t)RFIFOL(fd,46);
- break;
- }
- }
- }
-
- RFIFOSKIP(fd,50);
-
- return 0;
-}
-
-// changesex reply (modified by [Yor])
-int change_sex_reply(int fd, int len) {
- if (len < 7)
- return -1;
-
- int acc, sex, i;
- unsigned char buf[16];
- struct char_session_data *sd;
-
- acc = RFIFOL(fd,2);
- sex = RFIFOB(fd,6);
- RFIFOSKIP(fd, 7);
-
- if (acc > 0) {
- sprintf(tmp_sql, "SELECT `char_id`,`class`,`skill_point` FROM `%s` WHERE `account_id` = '%d'",char_db, acc);
- sql_query(tmp_sql,"change_sex_reply");
-
- if ((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res))) {
- int char_id, jobclass, skill_point, char_class;
-
- char_id = atoi(sql_row[0]);
- jobclass = atoi(sql_row[1]);
- skill_point = atoi(sql_row[2]);
- char_class = jobclass;
-
- if (jobclass == 19 || jobclass == 20 ||
- jobclass == 4020 || jobclass == 4021 ||
- jobclass == 4042 || jobclass == 4043) {
-
- // job modification
- if (jobclass == 19 || jobclass == 20) {
- char_class = (sex) ? 19 : 20;
- } else if (jobclass == 4020 || jobclass == 4021) {
- char_class = (sex) ? 4020 : 4021;
- } else if (jobclass == 4042 || jobclass == 4043) {
- char_class = (sex) ? 4042 : 4043;
- }
-
- // remove specifical skills of classes 19,20 4020,4021 and 4042,4043
- sprintf(tmp_sql, "SELECT `lv` FROM `%s` WHERE `char_id` = '%d' AND `id` >= '315' AND `id` <= '330'",skill_db, char_id);
- sql_query(tmp_sql,"change_sex_reply");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
- while(( sql_row = mysql_fetch_row(sql_res))) {
- skill_point += atoi(sql_row[0]);
- }
- }
-
- sprintf(tmp_sql, "DELETE FROM `%s` WHERE `char_id` = '%d' AND `id` >= '315' AND `id` <= '330'",skill_db, char_id);
- sql_query(tmp_sql,"change_sex_reply");
-
- // to avoid any problem with equipment and invalid sex, equipment is unequiped.
- sprintf(tmp_sql, "UPDATE `%s` SET `equip` = '0' WHERE `char_id` = '%d'",inventory_db, char_id);
- sql_query(tmp_sql,"change_sex_reply");
-
- sprintf(tmp_sql, "UPDATE `%s` SET `class`='%d' , `skill_point`='%d' , `weapon`='0' , `shield='0' , `head_top`='0' , `head_mid`='0' , `head_bottom`='0' WHERE `char_id` = '%d'",char_db, char_class, skill_point, char_id);
- sql_query(tmp_sql,"change_sex_reply");
- }
- }
-
- // disconnect player if online on char-server
- for(i = 0; i < fd_max; i++) {
- if (session[i] && (sd = session[i]->session_data)) {
- if (sd->account_id == acc) {
- session[i]->eof = 1;
- break;
- }
- }
- }
-
- WBUFW(buf,0) = 0x2b0d;
- WBUFL(buf,2) = acc;
- WBUFB(buf,6) = sex;
- mapif_sendall(buf, 7);
- }
-
- return 0;
-}
-
-int account_reg2(int fd, int len) {
- if (len < 4 || len < RFIFOW(fd,2))
- return -1;
-
- struct global_reg reg[ACCOUNT_REG2_NUM];
- unsigned char buf[4096];
- int j, p, acc;
-
- acc = RFIFOL(fd,4);
-
- for(p = 8, j = 0; p < RFIFOW(fd,2) && j < ACCOUNT_REG2_NUM; p += 36, j++) {
- memcpy(reg[j].str, RFIFOP(fd,p), 32);
- reg[j].value = RFIFOL(fd,p+32);
- }
-
- // set_account_reg2(acc,j,reg);
- // “¯CƒƒOƒCƒ“‚ð‹ÖŽ~‚µ‚Ä‚¢‚ê‚Α—‚é•K—v‚Í–³‚¢
- memcpy(buf,RFIFOP(fd,0), RFIFOW(fd,2));
- WBUFW(buf,0) = 0x2b11;
- mapif_sendall(buf, WBUFW(buf,2));
- RFIFOSKIP(fd, RFIFOW(fd,2));
-
- #ifdef DEBUG
- printf("char: save_account_reg_reply\n");
- #endif
-
- return 0;
-}
-
-// State change of account/ban notification (from login-server) by [Yor]
-int change_state_reply(int fd, int len) {
- if (len < 11)
- return -1;
-
+int parse_tologin(int fd) {
int i;
struct char_session_data *sd;
- // send to all map-servers to disconnect the player
- unsigned char buf[16];
- WBUFW(buf,0) = 0x2b14;
- WBUFL(buf,2) = RFIFOL(fd,2);
- WBUFB(buf,6) = RFIFOB(fd,6); // 0: change of statut, 1: ban
- WBUFL(buf,7) = RFIFOL(fd,7); // status or final date of a banishment
- mapif_sendall(buf, 11);
-
- // disconnect player if online on char-server
- for(i = 0; i < fd_max; i++) {
- if (session[i] && (sd = session[i]->session_data)) {
- if (sd->account_id == RFIFOL(fd,2)) {
- session[i]->eof = 1;
- break;
- }
- }
- }
-
- RFIFOSKIP(fd,11);
-
- return 0;
-}
-
-int parse_tologin(int fd) {
- int len,res = 0;
-
// only login-server can have an access to here.
// so, if it isn't the login-server, we disconnect the session.
//session eof check!
if(fd != login_fd)
session[fd]->eof = 1;
-
if(session[fd]->eof) {
if (fd == login_fd) {
printf("Char-server can't connect to login-server (connection #%d).\n", fd);
- delete_timer(user_count_timer,send_users_tologin);
login_fd = -1;
}
close(fd);
@@ -1475,570 +1472,826 @@ int parse_tologin(int fd) {
return 0;
}
+ sd = (struct char_session_data*)session[fd]->session_data;
+
// hehe. no need to set user limite on SQL version. :P
// but char limitation is good way to maintain server. :D
- len = RFIFOREST(fd);
- while(len >= 2 && res == 0) {
- #ifdef DEBUG
- printf("parse_tologin : %d %d %x\n", fd, RFIFOREST(fd), RFIFOW(fd, 0));
- #endif
+ while(RFIFOREST(fd) >= 2) {
+// printf("parse_tologin : %d %d %x\n", fd, RFIFOREST(fd), RFIFOW(fd, 0));
switch(RFIFOW(fd, 0)){
- case 0x2711: res = reply_login_request(fd,len); break;
- case 0x2713: res = send_chars(fd,len); break;
- case 0x2717: res = connect_until_reply(fd,len); break;
- case 0x2723: res = change_sex_reply(fd,len); break;
- case 0x2729: res = account_reg2(fd,len); break;
- case 0x2731: res = change_state_reply(fd,len); break;
- case 0x2732: res = read_gm_accounts(fd,len); break;
-
- default:
- printf("set eof.\n");
- session[fd]->eof = 1;
- return 0;
- }
-
- len = RFIFOREST(fd);
- }
-
- RFIFOFLUSH(fd);
-
- return 0;
-}
-
-//--------------------------------
-// Map-server anti-freeze system
-//--------------------------------
-int map_anti_freeze_system(int tid, unsigned int tick, int id, int data) {
- int i;
+ case 0x2711:
+ if (RFIFOREST(fd) < 3)
+ return 0;
+ if (RFIFOB(fd, 2)) {
+ //printf("connect login server error : %d\n", RFIFOB(fd, 2));
+ printf("Can not connect to login-server.\n");
+ printf("The server communication passwords (default s1/p1) is probably invalid.\n");
+ printf("Also, please make sure your login db has the username/password present and the sex of the account is S.\n");
+ printf("If you changed the communication passwords, change them back at map_athena.conf and char_athena.conf\n");
+ return 0;
+ //exit(1); //fixed for server shutdown.
+ }else {
+ printf("Connected to login-server (connection #%d).\n", fd);
+ set_all_offline();
+ // if no map-server already connected, display a message...
+ for(i = 0; i < MAX_MAP_SERVERS; i++)
+ if (server_fd[i] >= 0 && server[i].map[0][0]) // if map-server online and at least 1 map
+ break;
+ if (i == MAX_MAP_SERVERS)
+ printf("Awaiting maps from map-server.\n");
+ }
+ RFIFOSKIP(fd, 3);
+ break;
- for(i = 0; i < MAX_MAP_SERVERS; i++) {
- if (server_fd[i] >= 0) {// if map-server is online
- printf("map_anti_freeze_system: server #%d, flag: %d.\n", i, server_freezeflag[i]);
- if (server_freezeflag[i]-- < 1) {// Map-server anti-freeze system. Counter. 5 ok, 4...0 freezed
- printf("Map-server anti-freeze system: char-server #%d is frozen -> disconnection.\n", i);
- session[server_fd[i]]->eof = 1;
- sprintf(tmp_sql, "DELETE FROM `ragsrvinfo` WHERE `index`='%d'", server_fd[i]);
- if (mysql_query(&mysql_handle, tmp_sql)) {
- printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ case 0x2713:
+ if(RFIFOREST(fd)<51)
+ return 0;
+ for(i = 0; i < fd_max; i++) {
+ if (session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == RFIFOL(fd,2)) {
+ if (RFIFOB(fd,6) != 0) {
+ WFIFOW(i,0) = 0x6c;
+ WFIFOB(i,2) = 0x42;
+ WFIFOSET(i,3);
+ } else if (max_connect_user == 0 || count_users() < max_connect_user) {
+// if (max_connect_user == 0)
+// printf("max_connect_user (unlimited) -> accepted.\n");
+// else
+// printf("count_users(): %d < max_connect_user (%d) -> accepted.\n", count_users(), max_connect_user);
+ sd->connect_until_time = (time_t)RFIFOL(fd,47);
+ // send characters to player
+ mmo_char_send006b(i, sd);
+ } else if(isGM(sd->account_id) >= gm_allow_level) {
+ sd->connect_until_time = (time_t)RFIFOL(fd,47);
+ // send characters to player
+ mmo_char_send006b(i, sd);
+ } else {
+ // refuse connection: too much online players
+// printf("count_users(): %d < max_connect_use (%d) -> fail...\n", count_users(), max_connect_user);
+ WFIFOW(i,0) = 0x6c;
+ WFIFOW(i,2) = 0;
+ WFIFOSET(i,3);
+ }
}
}
- }
- }
-
- return 0;
-}
-
-int recv_map_names(int fd, int len, unsigned char id) {
- if (len < 4 || len < RFIFOW(fd,2))
- return -1;
-
- memset(server[id].map, 0, sizeof(server[id].map));
-
- int j = 0,i;
- unsigned char buf[16384];
- int x;
-
- for(i = 4; i < RFIFOW(fd,2); i += 16) {
- memcpy(server[id].map[j], RFIFOP(fd,i), 16);
-// printf("set map %d.%d : %s\n", id, j, server[id].map[j]);
- j++;
- }
-
- i = server[id].ip;
-
- unsigned char *p = (unsigned char *)&server[id].ip;
-
- printf("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d.\n",
- id, j, p[0], p[1], p[2], p[3], server[id].port);
-
-
- WFIFOW(fd,0) = 0x2afb;
- WFIFOB(fd,2) = 0;
- memcpy(WFIFOP(fd,3), wisp_server_name, 24); // name for wisp to player
- WFIFOSET(fd,27);
-
-
- if (j == 0) {
- printf("WARNING: Map-Server %d have NO maps.\n", id);
- } else {
- // Transmitting maps information to the other map-servers
- WBUFW(buf,0) = 0x2b04;
- WBUFW(buf,2) = j * 16 + 10;
- WBUFL(buf,4) = server[id].ip;
- WBUFW(buf,8) = server[id].port;
- memcpy(WBUFP(buf,10), RFIFOP(fd,4), j * 16);
- mapif_sendallwos(fd, buf, WBUFW(buf,2));
- }
-
- // Transmitting the maps of the other map-servers to the new map-server
- for(x = 0; x < MAX_MAP_SERVERS; x++) {
- if (server_fd[x] >= 0 && x != id) {
- WFIFOW(fd,0) = 0x2b04;
- WFIFOL(fd,4) = server[x].ip;
- WFIFOW(fd,8) = server[x].port;
+ RFIFOSKIP(fd,51);
+ break;
- j = 0;
+ case 0x2717:
+ if (RFIFOREST(fd) < 50)
+ return 0;
+ for(i = 0; i < fd_max; i++) {
+ if (session[i] && (sd = (struct char_session_data*)session[i]->session_data)) {
+ if (sd->account_id == RFIFOL(fd,2)) {
+ sd->connect_until_time = (time_t)RFIFOL(fd,46);
+ break;
+ }
+ }
+ }
+ RFIFOSKIP(fd,50);
+ break;
- for(i = 0; i < MAX_MAP_PER_SERVER; i++)
- if (server[x].map[i][0])
- memcpy(WFIFOP(fd,10+(j++)*16), server[x].map[i], 16);
+ // login-server alive packet
+ case 0x2718:
+ if (RFIFOREST(fd) < 2)
+ return 0;
+ RFIFOSKIP(fd,2);
+ break;
- if (j > 0) {
- WFIFOW(fd,2) = j * 16 + 10;
- WFIFOSET(fd,WFIFOW(fd,2));
+ // Receiving authentification from Freya-type login server (to avoid char->login->char)
+ case 0x2719:
+ if (RFIFOREST(fd) < 18)
+ return 0;
+ // to conserv a maximum of authentification, search if account is already authentified and replace it
+ // that will reduce multiple connection too
+ for(i = 0; i < AUTH_FIFO_SIZE; i++)
+ if (auth_fifo[i].account_id == RFIFOL(fd,2))
+ break;
+ // if not found, use next value
+ if (i == AUTH_FIFO_SIZE) {
+ if (auth_fifo_pos >= AUTH_FIFO_SIZE)
+ auth_fifo_pos = 0;
+ i = auth_fifo_pos;
+ auth_fifo_pos++;
}
- }
- }
-
- RFIFOSKIP(fd,RFIFOW(fd,2));
+ //printf("auth_fifo set (auth #%d) - account: %d, secure: %08x-%08x\n", i, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10));
+ auth_fifo[i].account_id = RFIFOL(fd,2);
+ auth_fifo[i].char_id = 0;
+ auth_fifo[i].login_id1 = RFIFOL(fd,6);
+ auth_fifo[i].login_id2 = RFIFOL(fd,10);
+ auth_fifo[i].delflag = 2; // 0: auth_fifo canceled/void, 2: auth_fifo received from login/map server in memory, 1: connection authentified
+ auth_fifo[i].char_pos = 0;
+ auth_fifo[i].connect_until_time = 0; // unlimited/unknown time by default (not display in map-server)
+ auth_fifo[i].ip = RFIFOL(fd,14);
+ //auth_fifo[i].map_auth = 0;
+ RFIFOSKIP(fd,18);
+ break;
- printf("Map-server %d loading complete.\n", id);
+/* case 0x2721: // gm reply. I don't want to support this function.
+ printf("0x2721:GM reply\n");
+ {
+ int oldacc, newacc;
+ unsigned char buf[64];
+ if (RFIFOREST(fd) < 10)
+ return 0;
+ oldacc = RFIFOL(fd, 2);
+ newacc = RFIFOL(fd, 6);
+ RFIFOSKIP(fd, 10);
+ if (newacc > 0) {
+ for(i=0;i<char_num;i++){
+ if(char_dat[i].account_id==oldacc)
+ char_dat[i].account_id=newacc;
+ }
+ }
+ WBUFW(buf,0)=0x2b0b;
+ WBUFL(buf,2)=oldacc;
+ WBUFL(buf,6)=newacc;
+ mapif_sendall(buf,10);
+// printf("char -> map\n");
+ }
+ break;
+*/
+ case 0x2723: // changesex reply (modified by [Yor])
+ if (RFIFOREST(fd) < 7)
+ return 0;
+ {
+ int acc, sex;
+ unsigned char buf[16];
+
+ acc = RFIFOL(fd,2);
+ sex = RFIFOB(fd,6);
+ RFIFOSKIP(fd, 7);
+ if (acc > 0) {
+ sprintf(tmp_sql, "SELECT `char_id`,`class`,`skill_point` FROM `%s` WHERE `account_id` = '%d'",char_db, acc);
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (select `char`)- %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle);
+
+ if (sql_res) {
+ int char_id, jobclass, skill_point, class_;
+ sql_row = mysql_fetch_row(sql_res);
+ char_id = atoi(sql_row[0]);
+ jobclass = atoi(sql_row[1]);
+ skill_point = atoi(sql_row[2]);
+ class_ = jobclass;
+ if (jobclass == 19 || jobclass == 20 ||
+ jobclass == 4020 || jobclass == 4021 ||
+ jobclass == 4042 || jobclass == 4043) {
+ // job modification
+ if (jobclass == 19 || jobclass == 20) {
+ class_ = (sex) ? 19 : 20;
+ } else if (jobclass == 4020 || jobclass == 4021) {
+ class_ = (sex) ? 4020 : 4021;
+ } else if (jobclass == 4042 || jobclass == 4043) {
+ class_ = (sex) ? 4042 : 4043;
+ }
+ // remove specifical skills of classes 19,20 4020,4021 and 4042,4043
+ sprintf(tmp_sql, "SELECT `lv` FROM `%s` WHERE `char_id` = '%d' AND `id` >= '315' AND `id` <= '330'",skill_db, char_id);
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (select `char`)- %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle);
+ if (sql_res) {
+ while(( sql_row = mysql_fetch_row(sql_res))) {
+ skill_point += atoi(sql_row[0]);
+ }
+ }
+ sprintf(tmp_sql, "DELETE FROM `%s` WHERE `char_id` = '%d' AND `id` >= '315' AND `id` <= '330'",skill_db, char_id);
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (select `char`)- %s\n", mysql_error(&mysql_handle));
+ }
+ }
+ // to avoid any problem with equipment and invalid sex, equipment is unequiped.
+ sprintf(tmp_sql, "UPDATE `%s` SET `equip` = '0' WHERE `char_id` = '%d'",inventory_db, char_id);
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (select `char`)- %s\n", mysql_error(&mysql_handle));
+ }
+ sprintf(tmp_sql, "UPDATE `%s` SET `class`='%d' , `skill_point`='%d' , `weapon`='0' , `shield='0' , `head_top`='0' , `head_mid`='0' , `head_bottom`='0' WHERE `char_id` = '%d'",char_db, class_, skill_point, char_id);
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (select `char`)- %s\n", mysql_error(&mysql_handle));
+ }
+ }
+ }
+ // disconnect player if online on char-server
+ for(i = 0; i < fd_max; i++) {
+ if (session[i] && (sd = (struct char_session_data*)session[i]->session_data)) {
+ if (sd->account_id == acc) {
+ session[i]->eof = 1;
+ break;
+ }
+ }
+ }
- servers_connected++;
+ WBUFW(buf,0) = 0x2b0d;
+ WBUFL(buf,2) = acc;
+ WBUFB(buf,6) = sex;
- return 0;
-}
+ mapif_sendall(buf, 7);
+ }
+ break;
-int auth_request(int fd, int len) {
- if (len < 22)
- return -1;
+ // account_reg2•ÏX’Ê’m
+ case 0x2729:
+ if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
+ return 0;
+ {
+ struct global_reg reg[ACCOUNT_REG2_NUM];
+ unsigned char buf[4096];
+ int j, p, acc;
+ acc = RFIFOL(fd,4);
+ for(p = 8, j = 0; p < RFIFOW(fd,2) && j < ACCOUNT_REG2_NUM; p += 36, j++) {
+ memcpy(reg[j].str, RFIFOP(fd,p), 32);
+ reg[j].value = RFIFOL(fd,p+32);
+ }
+ // set_account_reg2(acc,j,reg);
+ // “¯CƒƒOƒCƒ“‚ð‹ÖŽ~‚µ‚Ä‚¢‚ê‚Α—‚é•K—v‚Í–³‚¢
+ memcpy(buf,RFIFOP(fd,0), RFIFOW(fd,2));
+ WBUFW(buf,0) = 0x2b11;
+ mapif_sendall(buf, WBUFW(buf,2));
+ RFIFOSKIP(fd, RFIFOW(fd,2));
+// printf("char: save_account_reg_reply\n");
+ }
+ break;
- int i;
+ // State change of account/ban notification (from login-server) by [Yor]
+ case 0x2731:
+ if (RFIFOREST(fd) < 11)
+ return 0;
+ // send to all map-servers to disconnect the player
+ {
+ unsigned char buf[16];
+ WBUFW(buf,0) = 0x2b14;
+ WBUFL(buf,2) = RFIFOL(fd,2);
+ WBUFB(buf,6) = RFIFOB(fd,6); // 0: change of statut, 1: ban
+ WBUFL(buf,7) = RFIFOL(fd,7); // status or final date of a banishment
+ mapif_sendall(buf, 11);
+ }
+ // disconnect player if online on char-server
+ for(i = 0; i < fd_max; i++) {
+ if (session[i] && (sd = (struct char_session_data*)session[i]->session_data)) {
+ if (sd->account_id == RFIFOL(fd,2)) {
+ session[i]->eof = 1;
+ break;
+ }
+ }
+ }
+ RFIFOSKIP(fd,11);
+ break;
- #ifdef DEBUG
- printf("(AUTH request) auth_fifo search %d %d %d\n", RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOL(fd, 10));
- #endif
+ // Receive GM accounts [Freya login server packet by Yor]
+ case 0x2733:
+ // add test here to remember that the login-server is Freya-type
+ // sprintf (login_server_type, "Freya");
+ if (RFIFOREST(fd) < 7)
+ return 0;
+ {
+ int new_level = 0;
+ for(i = 0; i < GM_num; i++)
+ if (gm_account[i].account_id == RFIFOL(fd,2)) {
+ if (gm_account[i].level != (int)RFIFOB(fd,6)) {
+ gm_account[i].level = (int)RFIFOB(fd,6);
+ new_level = 1;
+ }
+ break;
+ }
+ // if not found, add it
+ if (i == GM_num) {
+ // limited to 4000, because we send information to char-servers (more than 4000 GM accounts???)
+ // int (id) + int (level) = 8 bytes * 4000 = 32k (limit of packets in windows)
+ if (((int)RFIFOB(fd,6)) > 0 && GM_num < 4000) {
+ if (GM_num == 0) {
+ gm_account = (struct gm_account*)aMalloc(sizeof(struct gm_account));
+ } else {
+ gm_account = (struct gm_account*)aRealloc(gm_account, sizeof(struct gm_account) * (GM_num + 1));
+ }
+ gm_account[GM_num].account_id = RFIFOL(fd,2);
+ gm_account[GM_num].level = (int)RFIFOB(fd,6);
+ new_level = 1;
+ GM_num++;
+ if (GM_num >= 4000)
+ printf("***WARNING: 4000 GM accounts found. Next GM accounts are not readed.\n");
+ }
+ }
+ if (new_level == 1) {
+ printf("From login-server: receiving a GM account information (%d: level %d).\n", RFIFOL(fd,2), (int)RFIFOB(fd,6));
+ mapif_send_gmaccounts();
- for(i = 0; i < AUTH_FIFO_SIZE; i++) {
- if (auth_fifo[i].account_id == RFIFOL(fd,2) &&
- auth_fifo[i].char_id == RFIFOL(fd,6) &&
- auth_fifo[i].login_id1 == RFIFOL(fd,10) &&
-#if CMP_AUTHFIFO_LOGIN2 != 0
- // here, it's the only area where it's possible that we doesn't know login_id2 (map-server asks just after 0x72 packet, that doesn't given the value)
- (auth_fifo[i].login_id2 == RFIFOL(fd,14) || RFIFOL(fd,14) == 0) && // relate to the versions higher than 18
-#endif
- (!check_ip_flag || auth_fifo[i].ip == RFIFOL(fd,18)) &&
- !auth_fifo[i].delflag) {
-
- auth_fifo[i].delflag = 1;
- WFIFOW(fd,0) = 0x2afd;
- WFIFOW(fd,2) = 16 + sizeof(struct mmo_charstatus);
- WFIFOL(fd,4) = RFIFOL(fd,2);
- WFIFOL(fd,8) = auth_fifo[i].login_id2;
- WFIFOL(fd,12) = (unsigned long)auth_fifo[i].connect_until_time;
- mmo_char_fromsql(auth_fifo[i].char_id, char_dat, 1);
- char_dat[0].sex = auth_fifo[i].sex;
- memcpy(WFIFOP(fd,16), &char_dat[0], sizeof(struct mmo_charstatus));
- WFIFOSET(fd, WFIFOW(fd,2));
-
- #ifdef DEBUG
- printf("auth_fifo search success (auth #%d, account %d, character: %d).\n", i, RFIFOL(fd,2), RFIFOL(fd,6));
- #endif
+ //create_online_files(); // not change online file for only 1 player (in next timer, that will be done
+ // send gm acccounts level to map-servers
+ }
+ }
+ RFIFOSKIP(fd,7);
+ break;
+ default:
+ printf("set eof.\n");
+ session[fd]->eof = 1;
return 0;
}
}
- if (i == AUTH_FIFO_SIZE) {
- WFIFOW(fd,0) = 0x2afe;
- WFIFOL(fd,2) = RFIFOL(fd,2);
- WFIFOSET(fd,6);
-
- #ifdef DEBUG
- printf("(AUTH request) auth_fifo search error!\n");
- #endif
- }
-
- RFIFOSKIP(fd,22);
-
- return 0;
-}
-
-int set_map_users(int fd, int len, unsigned char id) {
- if (len < 6 || len < RFIFOW(fd,2))
- return -1;
-
- if (RFIFOW(fd,4) != server[id].users)
- printf("map user: %d\n", RFIFOW(fd,4));
-
- server[id].users = RFIFOW(fd,4);
-
- if(anti_freeze_enable)
- server_freezeflag[id] = 5; // Map anti-freeze system. Counter. 5 ok, 4...0 freezed
-
- RFIFOSKIP(fd,RFIFOW(fd,2));
+ RFIFOFLUSH(fd);
return 0;
}
-int save_char(int fd, int len) {
- if (len < 4 || len < RFIFOW(fd,2))
- return -1;
+int parse_frommap(int fd) {
+ int i = 0, j = 0;
+ int id;
- //check account
- sprintf(tmp_sql, "SELECT count(*) FROM `%s` WHERE `account_id` = '%d' AND `char_id`='%d'",char_db, RFIFOL(fd,4),RFIFOL(fd,8));
- sql_query(tmp_sql,"save_char");
+ // Sometimes fd=0, and it will cause server crash. Don't know why. :(
+ if (fd <= 0) {
+ printf("parse_frommap error fd=0\n");
+ return 0;
+ }
- if ((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res)))
- if (atoi(sql_row[0]) == 1) {
- memcpy(&char_dat[0], RFIFOP(fd,12), sizeof(struct mmo_charstatus));
- mmo_char_tosql(RFIFOL(fd,8), char_dat);
+ for(id = 0; id < MAX_MAP_SERVERS; id++)
+ if (server_fd[id] == fd)
+ break;
+ if(id == MAX_MAP_SERVERS)
+ session[fd]->eof = 1;
+ if(session[fd]->eof) {
+ if (id < MAX_MAP_SERVERS) {
+ memset(&server[id], 0, sizeof(struct mmo_map_server));
+ printf("Map-server %d (session #%d) has disconnected.\n", id, fd);
+ sprintf(tmp_sql, "DELETE FROM `ragsrvinfo` WHERE `index`='%d'", server_fd[id]);
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ server_fd[id] = -1;
}
+ close(fd);
+ delete_session(fd);
+ return 0;
+ }
- mysql_free_result(sql_res);
-
-
- RFIFOSKIP(fd,RFIFOW(fd,2));
-
- return 0;
-}
-
-int request_char_select(int fd, int len) {
- if (len < 18)
- return -1;
-
- if (auth_fifo_pos >= AUTH_FIFO_SIZE)
- auth_fifo_pos = 0;
-
- #ifdef DEBUG
- printf("(charselect) auth_fifo set %d - account_id:%08x login_id1:%08x\n", auth_fifo_pos, RFIFOL(fd, 2), RFIFOL(fd, 6));
- #endif
-
- auth_fifo[auth_fifo_pos].account_id = RFIFOL(fd, 2);
- auth_fifo[auth_fifo_pos].char_id = 0;
- auth_fifo[auth_fifo_pos].login_id1 = RFIFOL(fd, 6);
- auth_fifo[auth_fifo_pos].login_id2 = RFIFOL(fd,10);
- auth_fifo[auth_fifo_pos].delflag = 2;
- auth_fifo[auth_fifo_pos].char_pos = 0;
- auth_fifo[auth_fifo_pos].connect_until_time = 0; // unlimited/unknown time by default (not display in map-server)
- auth_fifo[auth_fifo_pos].ip = RFIFOL(fd,14);
- auth_fifo_pos++;
-
- WFIFOW(fd, 0) = 0x2b03;
- WFIFOL(fd, 2) = RFIFOL(fd, 2);
- WFIFOB(fd, 6) = 0;
- WFIFOSET(fd, 7);
-
- RFIFOSKIP(fd, 18);
-
- return 0;
-}
-
-int request_change_map(int fd, int len) {
- if (len < 49)
- return -1;
-
- if (auth_fifo_pos >= AUTH_FIFO_SIZE)
- auth_fifo_pos = 0;
-
- WFIFOW(fd, 0) = 0x2b06;
- memcpy(WFIFOP(fd,2), RFIFOP(fd,2), 42);
-
- #ifdef DEBUG
- printf("(map change) auth_fifo set %d - account_id:%08x login_id1:%08x\n", auth_fifo_pos, RFIFOL(fd, 2), RFIFOL(fd, 6));
- #endif
+ while(RFIFOREST(fd) >= 2) {
+// printf("parse_frommap : %d %d %x\n", fd, RFIFOREST(fd), RFIFOW(fd,0));
- auth_fifo[auth_fifo_pos].account_id = RFIFOL(fd, 2);
- auth_fifo[auth_fifo_pos].login_id1 = RFIFOL(fd, 6);
- auth_fifo[auth_fifo_pos].login_id2 = RFIFOL(fd,10);
- auth_fifo[auth_fifo_pos].char_id = RFIFOL(fd,14);
- auth_fifo[auth_fifo_pos].delflag = 0;
- auth_fifo[auth_fifo_pos].sex = RFIFOB(fd,44);
- auth_fifo[auth_fifo_pos].ip = RFIFOL(fd,45);
+ switch(RFIFOW(fd, 0)) {
- sprintf(tmp_sql, "SELECT count(*) FROM `%s` WHERE `account_id` = '%d' AND `char_id`='%d'", char_db, RFIFOL(fd,2), RFIFOL(fd,14));
- sql_query(tmp_sql,"request_map_change");
+ // map-server alive packet
+ case 0x2718:
+ if (RFIFOREST(fd) < 2)
+ return 0;
+ RFIFOSKIP(fd,2);
+ break;
- if ((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res))) {
+ case 0x2af7:
+ RFIFOSKIP(fd,2);
+ read_gm_account();
+ break;
- auth_fifo[auth_fifo_pos].char_pos = auth_fifo[auth_fifo_pos].char_id;
- auth_fifo_pos++;
+ // mapserver -> map names recv.
+ case 0x2afa:
+ if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
+ return 0;
+ memset(server[id].map, 0, sizeof(server[id].map));
+ j = 0;
+ for(i = 4; i < RFIFOW(fd,2); i += 16) {
+ memcpy(server[id].map[j], RFIFOP(fd,i), 16);
+// printf("set map %d.%d : %s\n", id, j, server[id].map[j]);
+ j++;
+ }
+ i = server[id].ip;
+ {
+ unsigned char *p = (unsigned char *)&server[id].ip;
+ printf("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d.\n",
+ id, j, p[0], p[1], p[2], p[3], server[id].port);
+ printf("Map-server %d loading complete.\n", id);
+ set_all_offline();
+ }
+ WFIFOW(fd,0) = 0x2afb;
+ WFIFOB(fd,2) = 0;
+ memcpy(WFIFOP(fd,3), wisp_server_name, 24); // name for wisp to player
+ WFIFOSET(fd,27);
+ {
+ unsigned char buf[16384];
+ int x;
+ if (j == 0) {
+ printf("WARNING: Map-Server %d have NO maps.\n", id);
+ // Transmitting maps information to the other map-servers
+ } else {
+ WBUFW(buf,0) = 0x2b04;
+ WBUFW(buf,2) = j * 16 + 10;
+ WBUFL(buf,4) = server[id].ip;
+ WBUFW(buf,8) = server[id].port;
+ memcpy(WBUFP(buf,10), RFIFOP(fd,4), j * 16);
+ mapif_sendallwos(fd, buf, WBUFW(buf,2));
+ }
+ // Transmitting the maps of the other map-servers to the new map-server
+ for(x = 0; x < MAX_MAP_SERVERS; x++) {
+ if (server_fd[x] >= 0 && x != id) {
+ WFIFOW(fd,0) = 0x2b04;
+ WFIFOL(fd,4) = server[x].ip;
+ WFIFOW(fd,8) = server[x].port;
+ j = 0;
+ for(i = 0; i < MAX_MAP_PER_SERVER; i++)
+ if (server[x].map[i][0])
+ memcpy(WFIFOP(fd,10+(j++)*16), server[x].map[i], 16);
+ if (j > 0) {
+ WFIFOW(fd,2) = j * 16 + 10;
+ WFIFOSET(fd,WFIFOW(fd,2));
+ }
+ }
+ }
+ }
+ RFIFOSKIP(fd,RFIFOW(fd,2));
+ break;
- WFIFOL(fd,6) = 0;
- }
+ // auth request
+ case 0x2afc:
+ if (RFIFOREST(fd) < 22)
+ return 0;
+// printf("(AUTH request) auth_fifo search %d %d %d\n", RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOL(fd, 10));
+ for(i = 0; i < AUTH_FIFO_SIZE; i++) {
+ if (auth_fifo[i].account_id == RFIFOL(fd,2) &&
+ auth_fifo[i].char_id == RFIFOL(fd,6) &&
+ auth_fifo[i].login_id1 == RFIFOL(fd,10) &&
+#if CMP_AUTHFIFO_LOGIN2 != 0
+ // here, it's the only area where it's possible that we doesn't know login_id2 (map-server asks just after 0x72 packet, that doesn't given the value)
+ (auth_fifo[i].login_id2 == RFIFOL(fd,14) || RFIFOL(fd,14) == 0) && // relate to the versions higher than 18
+#endif
+ (!check_ip_flag || auth_fifo[i].ip == RFIFOL(fd,18)) &&
+ !auth_fifo[i].delflag) {
+ auth_fifo[i].delflag = 1;
+ WFIFOW(fd,0) = 0x2afd;
+ WFIFOW(fd,2) = 16 + sizeof(struct mmo_charstatus);
+ WFIFOL(fd,4) = RFIFOL(fd,2);
+ WFIFOL(fd,8) = auth_fifo[i].login_id2;
+ WFIFOL(fd,12) = (unsigned long)auth_fifo[i].connect_until_time;
+ mmo_char_fromsql(auth_fifo[i].char_id, char_dat, 1);
+ char_dat[0].sex = auth_fifo[i].sex;
+ memcpy(WFIFOP(fd,16), &char_dat[0], sizeof(struct mmo_charstatus));
+ WFIFOSET(fd, WFIFOW(fd,2));
+ //printf("auth_fifo search success (auth #%d, account %d, character: %d).\n", i, RFIFOL(fd,2), RFIFOL(fd,6));
+ break;
+ }
+ }
+ if (i == AUTH_FIFO_SIZE) {
+ WFIFOW(fd,0) = 0x2afe;
+ WFIFOL(fd,2) = RFIFOL(fd,2);
+ WFIFOSET(fd,6);
+// printf("(AUTH request) auth_fifo search error!\n");
+ }
+ RFIFOSKIP(fd,22);
+ break;
- if (atoi(sql_row[0]) == 0)
- WFIFOW(fd,6) = 1;
+ // set MAP user
+ case 0x2aff:
+ if (RFIFOREST(fd) < 6 || RFIFOREST(fd) < RFIFOW(fd,2))
+ return 0;
+ if (RFIFOW(fd,4) != server[id].users)
+ printf("[UserCount]: %d (Server: %d)\n", RFIFOW(fd,4), id);
+ server[id].users = RFIFOW(fd,4);
+ RFIFOSKIP(fd,RFIFOW(fd,2));
+ break;
- WFIFOSET(fd,44);
- RFIFOSKIP(fd,49);
+ // char saving
+ case 0x2b01:
+ i = 0;
+ if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
+ return 0;
+ //check account
+ sprintf(tmp_sql, "SELECT count(*) FROM `%s` WHERE `account_id` = '%d' AND `char_id`='%d'",char_db, RFIFOL(fd,4),RFIFOL(fd,8)); // TBR
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle);
+ if (sql_res) {
+ sql_row = mysql_fetch_row(sql_res);
+ if (sql_row)
+ i = atoi(sql_row[0]);
+ }
+ mysql_free_result(sql_res);
- mysql_free_result(sql_res);
+ if (i == 1) {
+ memcpy(&char_dat[0], RFIFOP(fd,12), sizeof(struct mmo_charstatus));
+ mmo_char_tosql(RFIFOL(fd,8), char_dat);
+ //save to DB
+ }
+ RFIFOSKIP(fd,RFIFOW(fd,2));
+ break;
- return 0;
-}
+ // req char selection
+ case 0x2b02:
+ if (RFIFOREST(fd) < 18)
+ return 0;
-int char_name_check(int fd, int len) {
- if (len < 6)
- return -1;
+ if (auth_fifo_pos >= AUTH_FIFO_SIZE)
+ auth_fifo_pos = 0;
+
+// printf("(charselect) auth_fifo set %d - account_id:%08x login_id1:%08x\n", auth_fifo_pos, RFIFOL(fd, 2), RFIFOL(fd, 6));
+ auth_fifo[auth_fifo_pos].account_id = RFIFOL(fd, 2);
+ auth_fifo[auth_fifo_pos].char_id = 0;
+ auth_fifo[auth_fifo_pos].login_id1 = RFIFOL(fd, 6);
+ auth_fifo[auth_fifo_pos].login_id2 = RFIFOL(fd,10);
+ auth_fifo[auth_fifo_pos].delflag = 2;
+ auth_fifo[auth_fifo_pos].char_pos = 0;
+ auth_fifo[auth_fifo_pos].connect_until_time = 0; // unlimited/unknown time by default (not display in map-server)
+ auth_fifo[auth_fifo_pos].ip = RFIFOL(fd,14);
+ auth_fifo_pos++;
+
+ WFIFOW(fd, 0) = 0x2b03;
+ WFIFOL(fd, 2) = RFIFOL(fd, 2);
+ WFIFOB(fd, 6) = 0;
+ WFIFOSET(fd, 7);
+
+ RFIFOSKIP(fd, 18);
+ break;
- WFIFOW(fd,0) = 0x2b09;
- WFIFOL(fd,2) = RFIFOL(fd,2);
+ // request "change map server"
+ case 0x2b05:
+ if (RFIFOREST(fd) < 49)
+ return 0;
- sprintf(tmp_sql, "SELECT `name` FROM `%s` WHERE `char_id`='%d'", char_db, RFIFOL(fd,2));
- sql_query(tmp_sql,"char_name_check");
+ if (auth_fifo_pos >= AUTH_FIFO_SIZE)
+ auth_fifo_pos = 0;
+
+ WFIFOW(fd, 0) = 0x2b06;
+ memcpy(WFIFOP(fd,2), RFIFOP(fd,2), 42);
+// printf("(map change) auth_fifo set %d - account_id:%08x login_id1:%08x\n", auth_fifo_pos, RFIFOL(fd, 2), RFIFOL(fd, 6));
+ printf("[MapChange] ");
+ auth_fifo[auth_fifo_pos].account_id = RFIFOL(fd, 2);
+ auth_fifo[auth_fifo_pos].login_id1 = RFIFOL(fd, 6);
+ auth_fifo[auth_fifo_pos].login_id2 = RFIFOL(fd,10);
+ auth_fifo[auth_fifo_pos].char_id = RFIFOL(fd,14);
+ auth_fifo[auth_fifo_pos].delflag = 0;
+ auth_fifo[auth_fifo_pos].sex = RFIFOB(fd,44);
+ auth_fifo[auth_fifo_pos].ip = RFIFOL(fd,45);
+
+ sprintf(tmp_sql, "SELECT `char_id`, `name` FROM `%s` WHERE `account_id` = '%d' AND `char_id`='%d'", char_db, RFIFOL(fd,2), RFIFOL(fd,14));
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle);
+ if(sql_res){
+ i = atoi(sql_row[0]);
+ printf("aid: %d, cid: %d, name: %s", RFIFOL(fd,2), atoi(sql_row[0]), sql_row[1]);
+ mysql_free_result(sql_res);
+ auth_fifo[auth_fifo_pos].char_pos = auth_fifo[auth_fifo_pos].char_id;
+ auth_fifo_pos++;
+ WFIFOL(fd,6) = 0;
+ }else{
+ printf("Error, aborted\n");
+ return 0;
+ }
+
+ if(i == 0){
+ WFIFOW(fd, 6) = 0;
+ }
+
+ WFIFOSET(fd, 44);
+ RFIFOSKIP(fd, 49);
+ printf(" done.\n");
+ /*
+ if (( sql_row = mysql_fetch_row(sql_res))) {
+ i = atoi(sql_row[0]);
+ mysql_free_result(sql_res);
+
+ auth_fifo[auth_fifo_pos].char_pos = auth_fifo[auth_fifo_pos].char_id;
+ auth_fifo_pos++;
+
+ WFIFOL(fd,6) = 0;
+ break;
+ }
+ if (i == 0)
+ WFIFOW(fd,6) = 1;
- if((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res)))
- memcpy(WFIFOP(fd,6), sql_row[0], 24);
- else
- memcpy(WFIFOP(fd,6), unknown_char_name, 24);
+ WFIFOSET(fd,44);
+ RFIFOSKIP(fd,49);
+ break;
+ */
- mysql_free_result(sql_res);
+ break;
+
+ // char name check
+ case 0x2b08:
+ if (RFIFOREST(fd) < 6)
+ return 0;
- WFIFOSET(fd,30);
+ sprintf(tmp_sql, "SELECT `name` FROM `%s` WHERE `char_id`='%d'", char_db, RFIFOL(fd,2));
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle);
- RFIFOSKIP(fd,6);
+ sql_row = mysql_fetch_row(sql_res);
- return 0;
-}
+ WFIFOW(fd,0) = 0x2b09;
+ WFIFOL(fd,2) = RFIFOL(fd,2);
-int account_reg(int fd, int len) {
- if (len < 4 || len < RFIFOW(fd,2))
- return -1;
+ if (sql_row)
+ memcpy(WFIFOP(fd,6), sql_row[0], 24);
+ else
+ memcpy(WFIFOP(fd,6), unknown_char_name, 24);
+ mysql_free_result(sql_res);
- struct global_reg reg[ACCOUNT_REG2_NUM];
- int j,p,acc;
- acc=RFIFOL(fd,4);
- for(p=8,j=0;p<RFIFOW(fd,2) && j<ACCOUNT_REG2_NUM;p+=36,j++){
- memcpy(reg[j].str,RFIFOP(fd,p),32);
- reg[j].value=RFIFOL(fd,p+32);
- }
+ WFIFOSET(fd,30);
- // set_account_reg2(acc,j,reg);
- // loginƒT[ƒo[‚Ö‘—‚é
- if (login_fd > 0) { // don't send request if no login-server
- WFIFOW(login_fd, 0) = 0x2728;
- memcpy(WFIFOP(login_fd,0), RFIFOP(fd,0), RFIFOW(fd,2));
- WFIFOSET(login_fd, WFIFOW(login_fd,2));
- }
+ RFIFOSKIP(fd,6);
+ break;
- // ƒ[ƒ‹ƒh‚Ö‚Ì“¯CƒƒOƒCƒ“‚ª‚È‚¯‚ê‚ÎmapƒT[ƒo[‚É‘—‚é•K—v‚͂Ȃ¢
- //memcpy(buf,RFIFOP(fd,0),RFIFOW(fd,2));
- //WBUFW(buf,0)=0x2b11;
- //mapif_sendall(buf,WBUFW(buf,2));
- RFIFOSKIP(fd,RFIFOW(fd,2));
+/* // I want become GM - fuck!
+ case 0x2b0a:
+ if(RFIFOREST(fd)<4)
+ return 0;
+ if(RFIFOREST(fd)<RFIFOW(fd,2))
+ return 0;
+ memcpy(WFIFOP(login_fd,2),RFIFOP(fd,2),RFIFOW(fd,2)-2);
+ WFIFOW(login_fd,0)=0x2720;
+ WFIFOSET(login_fd,RFIFOW(fd,2));
+// printf("char : change gm -> login %d %s %d\n", RFIFOL(fd, 4), RFIFOP(fd, 8), RFIFOW(fd, 2));
+ RFIFOSKIP(fd, RFIFOW(fd, 2));
+ break;
+ */
+ // account_reg•Û‘¶—v‹
+ case 0x2b10:
+ if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
+ return 0;
+ {
+ struct global_reg reg[ACCOUNT_REG2_NUM];
+ int j,p,acc;
+ acc=RFIFOL(fd,4);
+ for(p=8,j=0;p<RFIFOW(fd,2) && j<ACCOUNT_REG2_NUM;p+=36,j++){
+ memcpy(reg[j].str,RFIFOP(fd,p),32);
+ reg[j].value=RFIFOL(fd,p+32);
+ }
+ // set_account_reg2(acc,j,reg);
+ // loginƒT[ƒo[‚Ö‘—‚é
+ if (login_fd > 0) { // don't send request if no login-server
+ WFIFOW(login_fd, 0) = 0x2728;
+ memcpy(WFIFOP(login_fd,0), RFIFOP(fd,0), RFIFOW(fd,2));
+ WFIFOSET(login_fd, WFIFOW(login_fd,2));
+ }
+ // ƒ[ƒ‹ƒh‚Ö‚Ì“¯CƒƒOƒCƒ“‚ª‚È‚¯‚ê‚ÎmapƒT[ƒo[‚É‘—‚é•K—v‚͂Ȃ¢
+ //memcpy(buf,RFIFOP(fd,0),RFIFOW(fd,2));
+ //WBUFW(buf,0)=0x2b11;
+ //mapif_sendall(buf,WBUFW(buf,2));
+ RFIFOSKIP(fd,RFIFOW(fd,2));
// printf("char: save_account_reg (from map)\n");
+ }
+ break;
- return 0;
-}
-
-// Map server send information to change an email of an account -> login-server
-int change_email_request(int fd, int len) {
- if (len < 86)
- return -1;
-
- if (login_fd > 0) { // don't send request if no login-server
- memcpy(WFIFOP(login_fd,0), RFIFOP(fd,0), 86); // 0x2722 <account_id>.L <actual_e-mail>.40B <new_e-mail>.40B
- WFIFOW(login_fd,0) = 0x2722;
- WFIFOSET(login_fd, 86);
- }
-
- RFIFOSKIP(fd, 86);
-
- return 0;
-}
+ // Map server send information to change an email of an account -> login-server
+ case 0x2b0c:
+ if (RFIFOREST(fd) < 86)
+ return 0;
+ if (login_fd > 0) { // don't send request if no login-server
+ memcpy(WFIFOP(login_fd,0), RFIFOP(fd,0), 86); // 0x2722 <account_id>.L <actual_e-mail>.40B <new_e-mail>.40B
+ WFIFOW(login_fd,0) = 0x2722;
+ WFIFOSET(login_fd, 86);
+ }
+ RFIFOSKIP(fd, 86);
+ break;
-// Receiving from map-server a status change resquest. Transmission to login-server (by Yor)
-int status_change_request(int fd, int len) {
- if (len < 44)
- return -1;
+ // Receiving from map-server a status change resquest. Transmission to login-server (by Yor)
+ case 0x2b0e:
+ if (RFIFOREST(fd) < 44)
+ return 0;
+ {
+ char character_name[24];
+ int acc = RFIFOL(fd,2); // account_id of who ask (-1 if nobody)
+ memcpy(character_name, RFIFOP(fd,6), 24);
+ character_name[sizeof(character_name) -1] = '\0';
+ // prepare answer
+ WFIFOW(fd,0) = 0x2b0f; // answer
+ WFIFOL(fd,2) = acc; // who want do operation
+ WFIFOW(fd,30) = RFIFOW(fd, 30); // type of operation: 1-block, 2-ban, 3-unblock, 4-unban
+ sprintf(tmp_sql, "SELECT `account_id`,`name` FROM `%s` WHERE `name` = '%s'",char_db, character_name);
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error (select `char`)- %s\n", mysql_error(&mysql_handle));
+ }
- char character_name[24];
- int acc = RFIFOL(fd,2); // account_id of who ask (-1 if nobody)
-
- memcpy(character_name, RFIFOP(fd,6), 24);
- character_name[sizeof(character_name) -1] = '\0';
-
- // prepare answer
- WFIFOW(fd,0) = 0x2b0f; // answer
- WFIFOL(fd,2) = acc; // who want do operation
- WFIFOW(fd,30) = RFIFOW(fd, 30); // type of operation: 1-block, 2-ban, 3-unblock, 4-unban
-
- sprintf(tmp_sql, "SELECT `account_id`,`name` FROM `%s` WHERE `name` = '%s'",char_db, character_name);
- sql_query(tmp_sql,"status_change_request");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
- if ((sql_row = mysql_fetch_row(sql_res))) {
- memcpy(WFIFOP(fd,6), sql_row[1], 24); // put correct name if found
- WFIFOW(fd,32) = 0; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
-
- switch(RFIFOW(fd, 30)) {
- case 1: // block
- if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) {
- if (login_fd > 0) { // don't send request if no login-server
- WFIFOW(login_fd,0) = 0x2724;
- WFIFOL(login_fd,2) = atoi(sql_row[0]); // account value
- WFIFOL(login_fd,6) = 5; // status of the account
- WFIFOSET(login_fd, 10);
-// printf("char : status -> login: account %d, status: %d \n", char_dat[i].account_id, 5);
+ sql_res = mysql_store_result(&mysql_handle);
+
+ if (sql_res) {
+ if (mysql_num_rows(sql_res)) {
+ sql_row = mysql_fetch_row(sql_res);
+ memcpy(WFIFOP(fd,6), sql_row[1], 24); // put correct name if found
+ WFIFOW(fd,32) = 0; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
+ switch(RFIFOW(fd, 30)) {
+ case 1: // block
+ if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) {
+ if (login_fd > 0) { // don't send request if no login-server
+ WFIFOW(login_fd,0) = 0x2724;
+ WFIFOL(login_fd,2) = atoi(sql_row[0]); // account value
+ WFIFOL(login_fd,6) = 5; // status of the account
+ WFIFOSET(login_fd, 10);
+// printf("char : status -> login: account %d, status: %d \n", char_dat[i].account_id, 5);
+ } else
+ WFIFOW(fd,32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
} else
- WFIFOW(fd,32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
- } else
- WFIFOW(fd,32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
- break;
- case 2: // ban
- if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) {
- if (login_fd > 0) { // don't send request if no login-server
- WFIFOW(login_fd, 0) = 0x2725;
- WFIFOL(login_fd, 2) = atoi(sql_row[0]); // account value
- WFIFOW(login_fd, 6) = RFIFOW(fd,32); // year
- WFIFOW(login_fd, 8) = RFIFOW(fd,34); // month
- WFIFOW(login_fd,10) = RFIFOW(fd,36); // day
- WFIFOW(login_fd,12) = RFIFOW(fd,38); // hour
- WFIFOW(login_fd,14) = RFIFOW(fd,40); // minute
- WFIFOW(login_fd,16) = RFIFOW(fd,42); // second
- WFIFOSET(login_fd,18);
-// printf("char : status -> login: account %d, ban: %dy %dm %dd %dh %dmn %ds\n",
-// char_dat[i].account_id, (short)RFIFOW(fd,32), (short)RFIFOW(fd,34), (short)RFIFOW(fd,36), (short)RFIFOW(fd,38), (short)RFIFOW(fd,40), (short)RFIFOW(fd,42));
+ WFIFOW(fd,32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
+ break;
+ case 2: // ban
+ if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) {
+ if (login_fd > 0) { // don't send request if no login-server
+ WFIFOW(login_fd, 0) = 0x2725;
+ WFIFOL(login_fd, 2) = atoi(sql_row[0]); // account value
+ WFIFOW(login_fd, 6) = RFIFOW(fd,32); // year
+ WFIFOW(login_fd, 8) = RFIFOW(fd,34); // month
+ WFIFOW(login_fd,10) = RFIFOW(fd,36); // day
+ WFIFOW(login_fd,12) = RFIFOW(fd,38); // hour
+ WFIFOW(login_fd,14) = RFIFOW(fd,40); // minute
+ WFIFOW(login_fd,16) = RFIFOW(fd,42); // second
+ WFIFOSET(login_fd,18);
+// printf("char : status -> login: account %d, ban: %dy %dm %dd %dh %dmn %ds\n",
+// char_dat[i].account_id, (short)RFIFOW(fd,32), (short)RFIFOW(fd,34), (short)RFIFOW(fd,36), (short)RFIFOW(fd,38), (short)RFIFOW(fd,40), (short)RFIFOW(fd,42));
+ } else
+ WFIFOW(fd,32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
} else
- WFIFOW(fd,32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
- } else
- WFIFOW(fd,32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
- break;
- case 3: // unblock
- if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) {
- if (login_fd > 0) { // don't send request if no login-server
- WFIFOW(login_fd,0) = 0x2724;
- WFIFOL(login_fd,2) = atoi(sql_row[0]); // account value
- WFIFOL(login_fd,6) = 0; // status of the account
- WFIFOSET(login_fd, 10);
-// printf("char : status -> login: account %d, status: %d \n", char_dat[i].account_id, 0);
+ WFIFOW(fd,32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
+ break;
+ case 3: // unblock
+ if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) {
+ if (login_fd > 0) { // don't send request if no login-server
+ WFIFOW(login_fd,0) = 0x2724;
+ WFIFOL(login_fd,2) = atoi(sql_row[0]); // account value
+ WFIFOL(login_fd,6) = 0; // status of the account
+ WFIFOSET(login_fd, 10);
+// printf("char : status -> login: account %d, status: %d \n", char_dat[i].account_id, 0);
+ } else
+ WFIFOW(fd,32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
} else
- WFIFOW(fd,32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
- } else
- WFIFOW(fd,32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
- break;
- case 4: // unban
- if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) {
- if (login_fd > 0) { // don't send request if no login-server
- WFIFOW(login_fd, 0) = 0x272a;
- WFIFOL(login_fd, 2) = atoi(sql_row[0]); // account value
- WFIFOSET(login_fd, 6);
-// printf("char : status -> login: account %d, unban request\n", char_dat[i].account_id);
+ WFIFOW(fd,32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
+ break;
+ case 4: // unban
+ if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) {
+ if (login_fd > 0) { // don't send request if no login-server
+ WFIFOW(login_fd, 0) = 0x272a;
+ WFIFOL(login_fd, 2) = atoi(sql_row[0]); // account value
+ WFIFOSET(login_fd, 6);
+// printf("char : status -> login: account %d, unban request\n", char_dat[i].account_id);
+ } else
+ WFIFOW(fd,32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
} else
- WFIFOW(fd,32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
- } else
- WFIFOW(fd,32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
- break;
- case 5: // changesex
- if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) {
- if (login_fd > 0) { // don't send request if no login-server
- WFIFOW(login_fd, 0) = 0x2727;
- WFIFOL(login_fd, 2) = atoi(sql_row[0]); // account value
- WFIFOSET(login_fd, 6);
-// printf("char : status -> login: account %d, change sex request\n", char_dat[i].account_id);
+ WFIFOW(fd,32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
+ break;
+ case 5: // changesex
+ if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) {
+ if (login_fd > 0) { // don't send request if no login-server
+ WFIFOW(login_fd, 0) = 0x2727;
+ WFIFOL(login_fd, 2) = atoi(sql_row[0]); // account value
+ WFIFOSET(login_fd, 6);
+// printf("char : status -> login: account %d, change sex request\n", char_dat[i].account_id);
+ } else
+ WFIFOW(fd,32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
} else
- WFIFOW(fd,32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
- } else
- WFIFOW(fd,32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
- break;
- }
- } else {
- // character name not found
- memcpy(WFIFOP(fd,6), character_name, 24);
- WFIFOW(fd,32) = 1; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
- }
-
- // send answer if a player ask, not if the server ask
- if (acc != -1) {
- WFIFOSET(fd, 34);
- }
- }
-
- RFIFOSKIP(fd, 44);
-
- return 0;
-}
-
-int recieve_rates(int fd, int len) {
- if (len < 6 || len < RFIFOW(fd,8))
- return -1;
-
- sprintf(tmp_sql, "INSERT INTO `ragsrvinfo` SET `index`='%d',`name`='%s',`exp`='%d',`jexp`='%d',`drop`='%d',`motd`='%s'",
- fd, server_name, RFIFOW(fd,2), RFIFOW(fd,4), RFIFOW(fd,6), RFIFOP(fd,10));
- sql_query(tmp_sql,"recieve_rates");
-
- RFIFOSKIP(fd,RFIFOW(fd,8));
-
- return 0;
-}
-
-int set_offline(int fd, int len) {
- if (len < 6 )
- return -1;
-
- #ifdef DEBUG
- printf("Setting [%d] char offline\n",RFIFOL(fd,2));
- #endif
-
- sprintf(tmp_sql,"UPDATE `%s` SET `online`='0' WHERE `char_id`='%d'", char_db, RFIFOL(fd,2));
- sql_query(tmp_sql,"set_offline");
-
- RFIFOSKIP(fd,6);
-
- return 0;
-}
-
-int parse_frommap(int fd) {
- int len,res=0;
- unsigned char id;
-
- // Sometimes fd=0, and it will cause server crash. Don't know why. :(
- if (fd <= 0) {
- printf("parse_frommap error fd=0\n");
- return 0;
- }
-
- for(id = 0; id < MAX_MAP_SERVERS && id < servers_connected; id++)
- if (server_fd[id] == fd)
+ WFIFOW(fd,32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
+ break;
+ }
+ } else {
+ // character name not found
+ memcpy(WFIFOP(fd,6), character_name, 24);
+ WFIFOW(fd,32) = 1; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
+ }
+ // send answer if a player ask, not if the server ask
+ if (acc != -1) {
+ WFIFOSET(fd, 34);
+ }
+ }
+ }
+ RFIFOSKIP(fd, 44);
break;
- if(id == MAX_MAP_SERVERS || !servers_connected)
- session[fd]->eof = 1;
-
- if(session[fd]->eof) {
- if (servers_connected) {
- memset(&server[id], 0, sizeof(struct mmo_map_server));
-
- printf("Map-server %d (session #%d) has disconnected.\n", id, fd);
-
- sprintf(tmp_sql, "DELETE FROM `ragsrvinfo` WHERE `index`='%d'", server_fd[id]);
- sql_query(tmp_sql,"parse_frommap");
-
- server_fd[id] = -1;
-
- servers_connected--;
- }
- close(fd);
- delete_session(fd);
- return 0;
- }
-
- len = RFIFOREST(fd);
+ // Recieve rates [Wizputer]
+ case 0x2b16:
+ if (RFIFOREST(fd) < 6 || RFIFOREST(fd) < RFIFOW(fd,8))
+ return 0;
+ sprintf(tmp_sql, "INSERT INTO `ragsrvinfo` SET `index`='%d',`name`='%s',`exp`='%d',`jexp`='%d',`drop`='%d',`motd`='%s'",
+ fd, server_name, RFIFOW(fd,2), RFIFOW(fd,4), RFIFOW(fd,6), RFIFOP(fd,10));
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ RFIFOSKIP(fd,RFIFOW(fd,8));
+ break;
- while(len >= 2 && res == 0) {
- #ifdef DEBUG
- printf("parse_frommap : %d %d %x\n", fd, RFIFOREST(fd), RFIFOW(fd,0));
- #endif
+ // Character disconnected set online 0 [Wizputer]
+ case 0x2b17:
+ if (RFIFOREST(fd) < 6 )
+ return 0;
+ //printf("Setting %d char offline\n",RFIFOL(fd,2));
+ set_char_offline(RFIFOL(fd,2),RFIFOL(fd,6));
+ RFIFOSKIP(fd,10);
+ break;
+ // Reset all chars to offline [Wizputer]
+ case 0x2b18:
+ set_all_offline();
+ RFIFOSKIP(fd,2);
+ break;
+ // Character set online [Wizputer]
+ case 0x2b19:
+ if (RFIFOREST(fd) < 6 )
+ return 0;
+ //printf("Setting %d char online\n",RFIFOL(fd,2));
+ set_char_online(RFIFOL(fd,2),RFIFOL(fd,6));
+ RFIFOSKIP(fd,10);
+ break;
- switch(RFIFOW(fd, 0)) {
- case 0x2af7: res = read_gm_accounts(fd,len); break;
- case 0x2afa: res = recv_map_names(fd,len,id); break;
- case 0x2afc: res = auth_request(fd,len); break;
- case 0x2aff: res = set_map_users(fd,len,id); break;
- case 0x2b01: res = save_char(fd,len); break;
- case 0x2b02: res = request_char_select(fd,len); break;
- case 0x2b05: res = request_change_map(fd,len); break;
- case 0x2b08: res = char_name_check(fd,len); break;
- case 0x2b10: res = account_reg(fd,len); break;
- case 0x2b0c: res = change_email_request(fd,len); break;
- case 0x2b0e: res = status_change_request(fd,len); break;
- case 0x2b16: res = recieve_rates(fd,len); break;
- case 0x2b17: res = set_offline(fd,len); break;
-
- default:
+ default:
// inter server - packet
{
int r = inter_parse_frommap(fd);
@@ -2051,8 +2304,6 @@ int parse_frommap(int fd) {
session[fd]->eof = 1;
return 0;
}
-
- len = RFIFOREST(fd);
}
return 0;
}
@@ -2069,7 +2320,7 @@ int search_mapserver(char *map) {
temp_map[strchr(temp_map, '.') - temp_map + 1] = '\0'; // suppress the '.gat', but conserve the '.' to be sure of the name of the map
temp_map_len = strlen(temp_map);
- for(i = 0; i < MAX_MAP_SERVERS && i < servers_connected; i++)
+ for(i = 0; i < MAX_MAP_SERVERS; i++)
if (server_fd[i] >= 0)
for (j = 0; server[i].map[j][0]; j++)
//printf("%s : %s = %d\n", server[i].map[j], map, strncmp(server[i].map[j], temp_map, temp_map_len));
@@ -2112,470 +2363,568 @@ int lan_ip_check(unsigned char *p){
return lancheck;
}
-int client_request_connect(int fd, int len) {
- if (len < 17)
- return -1;
-
- struct char_session_data *sd = session[fd]->session_data;
- int i;
+int parse_char(int fd) {
+ int i, ch = 0;
+ char email[40];
+ unsigned short cmd;
+ struct char_session_data *sd;
+ unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
- #ifdef DEBUG
- printf("request connect - account_id:%d/login_id1:%d/login_id2:%d\n", RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOL(fd, 10));
- #endif
+ sd = (struct char_session_data*)session[fd]->session_data;
- if (sd == NULL) {
- CREATE(session[fd]->session_data, struct char_session_data, 1);
- sd = session[fd]->session_data;
- sd->connect_until_time = 0; // unknow or illimited (not displaying on map-server)
+ if(login_fd < 0)
+ session[fd]->eof = 1;
+ if(session[fd]->eof) {
+ if (fd == login_fd)
+ login_fd = -1;
+ if (sd != NULL)
+ set_char_offline(99,sd->account_id);
+ close(fd);
+ delete_session(fd);
+ return 0;
}
- sd->account_id = RFIFOL(fd, 2);
- sd->login_id1 = RFIFOL(fd, 6);
- sd->login_id2 = RFIFOL(fd, 10);
- sd->sex = RFIFOB(fd, 16);
+ while(RFIFOREST(fd) >= 2) {
+ cmd = RFIFOW(fd,0);
+ // crc32‚̃XƒLƒbƒv—p
+ if( sd==NULL && // –¢ƒƒOƒCƒ“orŠÇ—ƒpƒPƒbƒg
+ RFIFOREST(fd)>=4 && // Å’áƒoƒCƒg”§ŒÀ • 0x7530,0x7532ŠÇ—ƒpƒPœ‹Ž
+ RFIFOREST(fd)<=21 && // Å‘åƒoƒCƒg”§ŒÀ • ƒT[ƒo[ƒƒOƒCƒ“œ‹Ž
+ cmd!=0x20b && // md5’Ê’mƒpƒPƒbƒgœ‹Ž
+ (RFIFOREST(fd)<6 || RFIFOW(fd,4)==0x65) ){ // ŽŸ‚ɉ½‚©ƒpƒPƒbƒg‚ª—ˆ‚Ä‚é‚È‚çAÚ‘±‚łȂ¢‚Æ‚¾‚ß
+ RFIFOSKIP(fd,4);
+ cmd = RFIFOW(fd,0);
+ printf("parse_char : %d crc32 skipped\n",fd);
+ if(RFIFOREST(fd)==0)
+ return 0;
+ }
- WFIFOL(fd, 0) = RFIFOL(fd, 2);
- WFIFOSET(fd, 4);
+// if(cmd<30000 && cmd!=0x187)
+// printf("parse_char : %d %d %d\n",fd,RFIFOREST(fd),cmd);
- for(i = 0; i < AUTH_FIFO_SIZE; i++) {
- if(auth_fifo[i].account_id == sd->account_id &&
- auth_fifo[i].login_id1 == sd->login_id1 &&
-#if CMP_AUTHFIFO_LOGIN2 != 0
- auth_fifo[i].login_id2 == sd->login_id2 && // relate to the versions higher than 18
-#endif
- (!check_ip_flag || auth_fifo[i].ip == session[fd]->client_addr.sin_addr.s_addr) &&
- auth_fifo[i].delflag == 2) {
- auth_fifo[i].delflag = 1;
-
- if (max_connect_user == 0 || count_users() < max_connect_user) {
- if (login_fd > 0) { // don't send request if no login-server
- // request to login-server to obtain e-mail/time limit
- WFIFOW(login_fd,0) = 0x2716;
- WFIFOL(login_fd,2) = sd->account_id;
- WFIFOSET(login_fd,6);
- }
-
- // send characters to player
- mmo_char_send006b(fd, sd);
- } else {
- // refuse connection (over populated)
- WFIFOW(fd,0) = 0x6c;
- WFIFOW(fd,2) = 0;
- WFIFOSET(fd,3);
- }
-
- #ifdef DEBUG
- printf("connection request> set delflag 1(o:2)- account_id:%d/login_id1:%d(fifo_id:%d)\n", sd->account_id, sd->login_id1, i);
- #endif
-
- break;
- }
- }
- if (i == AUTH_FIFO_SIZE) {
- if (login_fd > 0) { // don't send request if no login-server
- WFIFOW(login_fd,0) = 0x2712; // ask login-server to authentify an account
- WFIFOL(login_fd,2) = sd->account_id;
- WFIFOL(login_fd,6) = sd->login_id1;
- WFIFOL(login_fd,10) = sd->login_id2;
- WFIFOB(login_fd,14) = sd->sex;
- WFIFOL(login_fd,15) = session[fd]->client_addr.sin_addr.s_addr;
- WFIFOSET(login_fd,19);
- } else { // if no login-server, we must refuse connection
- WFIFOW(fd,0) = 0x6c;
- WFIFOW(fd,2) = 0;
- WFIFOSET(fd,3);
- }
- }
+ // •s³ƒpƒPƒbƒg‚̈—
+// if (sd == NULL && cmd != 0x65 && cmd != 0x20b && cmd != 0x187 &&
+// cmd != 0x2af8 && cmd != 0x7530 && cmd != 0x7532)
+// cmd = 0xffff; // ƒpƒPƒbƒgƒ_ƒ“ƒv‚ð•\ަ‚³‚¹‚é
- #ifdef DEBUG
- if (isGM(RFIFOL(fd,2)))
- printf("Account Logged On; Account ID: %d (GM level %d).\n", RFIFOL(fd,2), isGM(RFIFOL(fd,2)));
- else
- printf("Account Logged On; Account ID: %d.\n", RFIFOL(fd,2));
- #endif
+ switch(cmd){
+ case 0x20b: //20040622 encryption ragexe correspondence
+ if (RFIFOREST(fd) < 19)
+ return 0;
+ RFIFOSKIP(fd,19);
+ break;
- RFIFOSKIP(fd, 17);
+ case 0x65: // request to connect
+ printf("request connect - account_id:%d/login_id1:%d/login_id2:%d\n", RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOL(fd, 10));
+ if (RFIFOREST(fd) < 17)
+ return 0;
+ {
+/*removed from isGM setup
+ if (isGM(RFIFOL(fd,2)))
+ printf("Account Logged On; Account ID: %d (GM level %d).\n", RFIFOL(fd,2), isGM(RFIFOL(fd,2)));
+ else
+ printf("Account Logged On; Account ID: %d.\n", RFIFOL(fd,2));
+*/
+ if (sd == NULL) {
+ CREATE(session[fd]->session_data, struct char_session_data, 1);
+ sd = (struct char_session_data*)session[fd]->session_data;
+ sd->connect_until_time = 0; // unknow or illimited (not displaying on map-server)
+ }
+ sd->account_id = RFIFOL(fd, 2);
+ sd->login_id1 = RFIFOL(fd, 6);
+ sd->login_id2 = RFIFOL(fd, 10);
+ sd->sex = RFIFOB(fd, 16);
- return 0;
-}
+ WFIFOL(fd, 0) = RFIFOL(fd, 2);
+ WFIFOSET(fd, 4);
-int char_select(int fd, int len, unsigned char *ip) {
- if (len < 3)
- return -1;
+ for(i = 0; i < AUTH_FIFO_SIZE; i++) {
+ if (auth_fifo[i].account_id == sd->account_id &&
+ auth_fifo[i].login_id1 == sd->login_id1 &&
+#if CMP_AUTHFIFO_LOGIN2 != 0
+ auth_fifo[i].login_id2 == sd->login_id2 && // relate to the versions higher than 18
+#endif
+ (!check_ip_flag || auth_fifo[i].ip == session[fd]->client_addr.sin_addr.s_addr) &&
+ auth_fifo[i].delflag == 2) {
+ auth_fifo[i].delflag = 1;
+
+ if (max_connect_user == 0 || count_users() < max_connect_user) {
+ if (login_fd > 0) { // don't send request if no login-server
+ // request to login-server to obtain e-mail/time limit
+ WFIFOW(login_fd,0) = 0x2716;
+ WFIFOL(login_fd,2) = sd->account_id;
+ WFIFOSET(login_fd,6);
+ }
+ // send characters to player
+ mmo_char_send006b(fd, sd);
+ } else {
+ // refuse connection (over populated)
+ WFIFOW(fd,0) = 0x6c;
+ WFIFOW(fd,2) = 0;
+ WFIFOSET(fd,3);
+ }
+// printf("connection request> set delflag 1(o:2)- account_id:%d/login_id1:%d(fifo_id:%d)\n", sd->account_id, sd->login_id1, i);
+ break;
+ }
+ }
+ if (i == AUTH_FIFO_SIZE) {
+ if (login_fd > 0) { // don't send request if no login-server
+ WFIFOW(login_fd,0) = 0x2712; // ask login-server to authentify an account
+ WFIFOL(login_fd,2) = sd->account_id;
+ WFIFOL(login_fd,6) = sd->login_id1;
+ WFIFOL(login_fd,10) = sd->login_id2;
+ WFIFOB(login_fd,14) = sd->sex;
+ WFIFOL(login_fd,15) = session[fd]->client_addr.sin_addr.s_addr;
+ WFIFOSET(login_fd,19);
+ } else { // if no login-server, we must refuse connection
+ WFIFOW(fd,0) = 0x6c;
+ WFIFOW(fd,2) = 0;
+ WFIFOSET(fd,3);
+ }
+ }
+ }
+ RFIFOSKIP(fd, 17);
+ break;
- int i;
- struct char_session_data *sd = session[fd]->session_data;
+ case 0x66: // char select
+// printf("0x66> request connect - account_id:%d/char_num:%d\n",sd->account_id,RFIFOB(fd, 2));
+ if (RFIFOREST(fd) < 3)
+ return 0;
- #ifdef DEBUG
- printf("0x66> request connect - account_id:%d/char_num:%d\n",sd->account_id,RFIFOB(fd, 2));
- #endif
+ if (sd == NULL)
+ return 0;
- sprintf(tmp_sql, "SELECT `char_id` FROM `%s` WHERE `account_id`='%d' AND `char_num`='%d'",char_db, sd->account_id, RFIFOB(fd, 2));
- sql_query(tmp_sql,"char_select");
+ sprintf(tmp_sql, "SELECT `char_id` FROM `%s` WHERE `account_id`='%d' AND `char_num`='%d'",char_db, sd->account_id, RFIFOB(fd, 2));
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle);
- if ((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res))) {
- mmo_char_fromsql(atoi(sql_row[0]), char_dat, 0);
- mysql_free_result(sql_res);
- } else {
- mysql_free_result(sql_res);
- RFIFOSKIP(fd, 3);
- return 0;
- }
+ sql_row = mysql_fetch_row(sql_res);
- sprintf(tmp_sql,"INSERT DELAYED INTO `%s`(`time`, `account_id`,`char_num`,`name`) VALUES (NOW(), '%d', '%d', '%s')",
- charlog_db, sd->account_id, RFIFOB(fd, 2), char_dat[0].name);
- sql_query(tmp_sql,"char_select");
+ if (sql_row)
+ mmo_char_fromsql(atoi(sql_row[0]), char_dat, 1);
+ else {
+ mysql_free_result(sql_res);
+ RFIFOSKIP(fd, 3);
+ break;
+ }
- #ifdef DEBUG
- printf("(\033[1;64m%d\033[0m) char selected (\033[1;32m%d\033[0m) \033[1;32m%s\033[0m" RETCODE, sd->account_id, RFIFOB(fd, 2), char_dat[0].name);
- #endif
+ if (log_char) {
+ sprintf(tmp_sql,"INSERT INTO `%s`(`time`, `account_id`,`char_num`,`name`) VALUES (NOW(), '%d', '%d', '%s')",
+ charlog_db, sd->account_id, RFIFOB(fd, 2), char_dat[0].name);
+ //query
+ if(mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ }
+ printf("(\033[1;64m%d\033[0m) char selected (\033[1;32m%d\033[0m) \033[1;32m%s\033[0m" RETCODE, sd->account_id, RFIFOB(fd, 2), char_dat[0].name);
+
+ i = search_mapserver(char_dat[0].last_point.map);
+
+ // if map is not found, we check major cities
+ if (i < 0) {
+ if ((i = search_mapserver("prontera.gat")) >= 0) { // check is done without 'gat'.
+ memcpy(char_dat[0].last_point.map, "prontera.gat", 16);
+ char_dat[0].last_point.x = 273; // savepoint coordonates
+ char_dat[0].last_point.y = 354;
+ } else if ((i = search_mapserver("geffen.gat")) >= 0) { // check is done without 'gat'.
+ memcpy(char_dat[0].last_point.map, "geffen.gat", 16);
+ char_dat[0].last_point.x = 120; // savepoint coordonates
+ char_dat[0].last_point.y = 100;
+ } else if ((i = search_mapserver("morocc.gat")) >= 0) { // check is done without 'gat'.
+ memcpy(char_dat[0].last_point.map, "morocc.gat", 16);
+ char_dat[0].last_point.x = 160; // savepoint coordonates
+ char_dat[0].last_point.y = 94;
+ } else if ((i = search_mapserver("alberta.gat")) >= 0) { // check is done without 'gat'.
+ memcpy(char_dat[0].last_point.map, "alberta.gat", 16);
+ char_dat[0].last_point.x = 116; // savepoint coordonates
+ char_dat[0].last_point.y = 57;
+ } else if ((i = search_mapserver("payon.gat")) >= 0) { // check is done without 'gat'.
+ memcpy(char_dat[0].last_point.map, "payon.gat", 16);
+ char_dat[0].last_point.x = 87; // savepoint coordonates
+ char_dat[0].last_point.y = 117;
+ } else if ((i = search_mapserver("izlude.gat")) >= 0) { // check is done without 'gat'.
+ memcpy(char_dat[0].last_point.map, "izlude.gat", 16);
+ char_dat[0].last_point.x = 94; // savepoint coordonates
+ char_dat[0].last_point.y = 103;
+ } else {
+ int j;
+ // get first online server
+ i = 0;
+ for(j = 0; j < MAX_MAP_SERVERS; j++)
+ if (server_fd[j] >= 0 && server[j].map[0][0]) {
+ i = j;
+ printf("Map-server #%d found with a map: '%s'.\n", j, server[j].map[0]);
+ break;
+ }
+ // if no map-servers are connected, we send: server closed
+ if (j == MAX_MAP_SERVERS) {
+ WFIFOW(fd,0) = 0x81;
+ WFIFOL(fd,2) = 1; // 01 = Server closed
+ WFIFOSET(fd,3);
+ RFIFOSKIP(fd,3);
+ break;
+ }
+ }
+ }
+ WFIFOW(fd, 0) =0x71;
+ WFIFOL(fd, 2) =char_dat[0].char_id;
+ memcpy(WFIFOP(fd, 6), char_dat[0].last_point.map, 16);
+ //Lan check added by Kashy
+ if (lan_ip_check(p))
+ WFIFOL(fd, 22) = inet_addr(lan_map_ip);
+ else
+ WFIFOL(fd, 22) = server[i].ip;
+ WFIFOW(fd, 26) = server[i].port;
+ WFIFOSET(fd, 28);
+
+ if (auth_fifo_pos >= AUTH_FIFO_SIZE) {
+ auth_fifo_pos = 0;
+ }
+// printf("auth_fifo set (auth_fifo_pos:%d) - account_id:%d char_id:%d login_id1:%d\n", auth_fifo_pos, sd->account_id, char_dat[0].char_id, sd->login_id1);
+ auth_fifo[auth_fifo_pos].account_id = sd->account_id;
+ auth_fifo[auth_fifo_pos].char_id = char_dat[0].char_id;
+ auth_fifo[auth_fifo_pos].login_id1 = sd->login_id1;
+ auth_fifo[auth_fifo_pos].login_id2 = sd->login_id2;
+ auth_fifo[auth_fifo_pos].delflag = 0;
+ //auth_fifo[auth_fifo_pos].char_pos = sd->found_char[ch];
+ auth_fifo[auth_fifo_pos].char_pos = 0;
+ auth_fifo[auth_fifo_pos].sex = sd->sex;
+ auth_fifo[auth_fifo_pos].connect_until_time = sd->connect_until_time;
+ auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr.sin_addr.s_addr;
+ auth_fifo_pos++;
+// printf("0x66> end\n");
+ RFIFOSKIP(fd, 3);
+ break;
- i = search_mapserver(char_dat[0].last_point.map);
-
- // if map is not found, we check major cities
- if (i < 0) {
- if ((i = search_mapserver("prontera.gat")) >= 0) { // check is done without 'gat'.
- memcpy(char_dat[0].last_point.map, "prontera.gat", 16);
- char_dat[0].last_point.x = 273; // savepoint coordonates
- char_dat[0].last_point.y = 354;
- } else if ((i = search_mapserver("geffen.gat")) >= 0) { // check is done without 'gat'.
- memcpy(char_dat[0].last_point.map, "geffen.gat", 16);
- char_dat[0].last_point.x = 120; // savepoint coordonates
- char_dat[0].last_point.y = 100;
- } else if ((i = search_mapserver("morocc.gat")) >= 0) { // check is done without 'gat'.
- memcpy(char_dat[0].last_point.map, "morocc.gat", 16);
- char_dat[0].last_point.x = 160; // savepoint coordonates
- char_dat[0].last_point.y = 94;
- } else if ((i = search_mapserver("alberta.gat")) >= 0) { // check is done without 'gat'.
- memcpy(char_dat[0].last_point.map, "alberta.gat", 16);
- char_dat[0].last_point.x = 116; // savepoint coordonates
- char_dat[0].last_point.y = 57;
- } else if ((i = search_mapserver("payon.gat")) >= 0) { // check is done without 'gat'.
- memcpy(char_dat[0].last_point.map, "payon.gat", 16);
- char_dat[0].last_point.x = 87; // savepoint coordonates
- char_dat[0].last_point.y = 117;
- } else if ((i = search_mapserver("izlude.gat")) >= 0) { // check is done without 'gat'.
- memcpy(char_dat[0].last_point.map, "izlude.gat", 16);
- char_dat[0].last_point.x = 94; // savepoint coordonates
- char_dat[0].last_point.y = 103;
- } else {
- int j;
- // get first online server
+ case 0x67: // make new
+// printf("0x67>request make new char\n");
+ if (RFIFOREST(fd) < 37)
+ return 0;
+ i = make_new_char_sql(fd, RFIFOP(fd, 2));
+
+ //if (i < 0) {
+ // WFIFOW(fd, 0) = 0x6e;
+ // WFIFOB(fd, 2) = 0x00;
+ // WFIFOSET(fd, 3);
+ // RFIFOSKIP(fd, 37);
+ // break;
+ //}
+ //Changed that we can support 'Charname already exists' (-1) amd 'Char creation denied' (-2)
+ //And 'You are underaged' (-3) (XD) [Sirius]
+ if(i == -1){
+ //already exists
+ WFIFOW(fd, 0) = 0x6e;
+ WFIFOB(fd, 2) = 0x00;
+ WFIFOSET(fd, 3);
+ RFIFOSKIP(fd, 37);
+ break;
+ }else if(i == -2){
+ //denied
+ WFIFOW(fd, 0) = 0x6e;
+ WFIFOB(fd, 2) = 0x02;
+ WFIFOSET(fd, 3);
+ RFIFOSKIP(fd, 37);
+ break;
+ }else if(i == -3){
+ //underaged XD
+ WFIFOW(fd, 0) = 0x6e;
+ WFIFOB(fd, 2) = 0x01;
+ WFIFOSET(fd, 3);
+ RFIFOSKIP(fd, 37);
+ break;
+ }
+
+ WFIFOW(fd, 0) = 0x6d;
+ memset(WFIFOP(fd, 2), 0x00, 106);
+
+ mmo_char_fromsql(i, char_dat, 0);
i = 0;
- for(j = 0; j < MAX_MAP_SERVERS && i < servers_connected; j++)
- if (server_fd[j] >= 0 && server[j].map[0][0]) {
- i = j;
- printf("Map-server #%d found with a map: '%s'.\n", j, server[j].map[0]);
+ WFIFOL(fd, 2) = char_dat[i].char_id;
+ WFIFOL(fd,2+4) = char_dat[i].base_exp;
+ WFIFOL(fd,2+8) = char_dat[i].zeny;
+ WFIFOL(fd,2+12) = char_dat[i].job_exp;
+ WFIFOL(fd,2+16) = char_dat[i].job_level;
+
+ WFIFOL(fd,2+28) = char_dat[i].karma;
+ WFIFOL(fd,2+32) = char_dat[i].manner;
+
+ WFIFOW(fd,2+40) = 0x30;
+ WFIFOW(fd,2+42) = (char_dat[i].hp > 0x7fff) ? 0x7fff : char_dat[i].hp;
+ WFIFOW(fd,2+44) = (char_dat[i].max_hp > 0x7fff) ? 0x7fff : char_dat[i].max_hp;
+ WFIFOW(fd,2+46) = (char_dat[i].sp > 0x7fff) ? 0x7fff : char_dat[i].sp;
+ WFIFOW(fd,2+48) = (char_dat[i].max_sp > 0x7fff) ? 0x7fff : char_dat[i].max_sp;
+ WFIFOW(fd,2+50) = DEFAULT_WALK_SPEED; // char_dat[i].speed;
+ WFIFOW(fd,2+52) = char_dat[i].class_;
+ WFIFOW(fd,2+54) = char_dat[i].hair;
+
+ WFIFOW(fd,2+58) = char_dat[i].base_level;
+ WFIFOW(fd,2+60) = char_dat[i].skill_point;
+
+ WFIFOW(fd,2+64) = char_dat[i].shield;
+ WFIFOW(fd,2+66) = char_dat[i].head_top;
+ WFIFOW(fd,2+68) = char_dat[i].head_mid;
+ WFIFOW(fd,2+70) = char_dat[i].hair_color;
+
+ memcpy(WFIFOP(fd,2+74), char_dat[i].name, 24);
+
+ WFIFOB(fd,2+98) = char_dat[i].str;
+ WFIFOB(fd,2+99) = char_dat[i].agi;
+ WFIFOB(fd,2+100) = char_dat[i].vit;
+ WFIFOB(fd,2+101) = char_dat[i].int_;
+ WFIFOB(fd,2+102) = char_dat[i].dex;
+ WFIFOB(fd,2+103) = char_dat[i].luk;
+ WFIFOB(fd,2+104) = char_dat[i].char_num;
+
+ WFIFOSET(fd, 108);
+ RFIFOSKIP(fd, 37);
+ //to do
+ for(ch = 0; ch < 9; ch++) {
+ if (sd->found_char[ch] == -1) {
+ sd->found_char[ch] = char_dat[i].char_id;
break;
}
- // if no map-servers are connected, we send: server closed
- if (j == MAX_MAP_SERVERS) {
- WFIFOW(fd,0) = 0x81;
- WFIFOL(fd,2) = 1; // 01 = Server closed
- WFIFOSET(fd,3);
- RFIFOSKIP(fd,3);
- return 0;
}
- }
- }
-
- WFIFOW(fd, 0) =0x71;
- WFIFOL(fd, 2) =char_dat[0].char_id;
- memcpy(WFIFOP(fd, 6), char_dat[0].last_point.map, 16);
-
- //Lan check added by Kashy
- if (lan_ip_check(ip))
- WFIFOL(fd, 22) = inet_addr(lan_map_ip);
- else
- WFIFOL(fd, 22) = server[i].ip;
-
- WFIFOW(fd, 26) = server[i].port;
- WFIFOSET(fd, 28);
- if (auth_fifo_pos >= AUTH_FIFO_SIZE)
- auth_fifo_pos = 0;
-
- #ifdef DEBUG
- printf("auth_fifo set (auth_fifo_pos:%d) - account_id:%d char_id:%d login_id1:%d\n", auth_fifo_pos, sd->account_id, char_dat[0].char_id, sd->login_id1);
- #endif
-
- auth_fifo[auth_fifo_pos].account_id = sd->account_id;
- auth_fifo[auth_fifo_pos].char_id = char_dat[0].char_id;
- auth_fifo[auth_fifo_pos].login_id1 = sd->login_id1;
- auth_fifo[auth_fifo_pos].login_id2 = sd->login_id2;
- auth_fifo[auth_fifo_pos].delflag = 0;
- //auth_fifo[auth_fifo_pos].char_pos = sd->found_char[ch];
- auth_fifo[auth_fifo_pos].char_pos = 0;
- auth_fifo[auth_fifo_pos].sex = sd->sex;
- auth_fifo[auth_fifo_pos].connect_until_time = sd->connect_until_time;
- auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr.sin_addr.s_addr;
- auth_fifo_pos++;
+ case 0x68: // delete
+ if (RFIFOREST(fd) < 46)
+ return 0;
+ printf("\033[1;31m Request Char Del:\033[0m \033[1;32m%d\033[0m(\033[1;32m%d\033[0m)\n", sd->account_id, RFIFOL(fd, 2));
+ memcpy(email, RFIFOP(fd,6), 40);
+ sprintf(tmp_sql, "SELECT `email` FROM `%s` WHERE `%s`='%d'",login_db, login_db_account_id, sd->account_id);
+ if (mysql_query(&lmysql_handle, tmp_sql)) {
+ printf("\033[1;31m DB server Error Delete Char data - %s \033[0m \n", mysql_error(&lmysql_handle));
+ }
+ sql_res = mysql_store_result(&lmysql_handle);
+ if (sql_res) {
+ sql_row = mysql_fetch_row(sql_res);
+
+ if ( (strcmp(email,sql_row[0]) == 0) || // client_value == db_value?
+ ((strcmp(email,"") == 0) &&
+ (strcmp(sql_row[0],"a@a.com") == 0)) ) { // client_value == "" && db_value == "a@a.com" ?
+ mysql_free_result(sql_res);
+ } else {
+ WFIFOW(fd, 0) = 0x70;
+ WFIFOB(fd, 2) = 0;
+ WFIFOSET(fd, 3);
+ RFIFOSKIP(fd, 46);
+ mysql_free_result(sql_res);
+ break;
+ }
+ } else {
+ WFIFOW(fd, 0) = 0x70;
+ WFIFOB(fd, 2) = 0;
+ WFIFOSET(fd, 3);
+ RFIFOSKIP(fd, 46);
+ mysql_free_result(sql_res);
+ break;
+ }
+ sprintf(tmp_sql, "SELECT `name`,`partner_id` FROM `%s` WHERE `char_id`='%d'",char_db, RFIFOL(fd,2));
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle);
+ if(sql_res)
+ sql_row = mysql_fetch_row(sql_res);
+
+ if (sql_res && sql_row[0]) {
+ //delete char from SQL
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `char_id`='%d'",pet_db, RFIFOL(fd, 2));
+ if(mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `char_id`='%d'",inventory_db, RFIFOL(fd, 2));
+ if(mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
-// printf("0x66> end\n");
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `char_id`='%d'",cart_db, RFIFOL(fd, 2));
+ if(mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
- RFIFOSKIP(fd, 3);
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `char_id`='%d'",memo_db, RFIFOL(fd, 2));
+ if(mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
- return 0;
-}
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `char_id`='%d'",skill_db, RFIFOL(fd, 2));
+ if(mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
-int make_new_char(int fd, int len) {
- if (len < 37)
- return -1;
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `char_id`='%d'",char_db, RFIFOL(fd, 2));
+ if(mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
- int i, ch;
- struct char_session_data *sd = session[fd]->session_data;
+ //Divorce [Wizputer]
+ if (sql_row[1] != 0) {
+ unsigned char buf[64];
+ sprintf(tmp_sql,"UPDATE `%s` SET `partner_id`='0' WHERE `char_id`='%d'",char_db,atoi(sql_row[1]));
+ if(mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE (`nameid`='%d' OR `nameid`='%d') AND `char_id`='%d'",inventory_db,WEDDING_RING_M,WEDDING_RING_F,atoi(sql_row[1]));
+ if(mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ WBUFW(buf,0) = 0x2b12;
+ WBUFL(buf,2) = atoi(sql_row[0]);
+ WBUFL(buf,6) = atoi(sql_row[1]);
+ mapif_sendall(buf,10);
+ }
+ // Also delete info from guildtables.
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `char_id`='%d'",guild_member_db, RFIFOL(fd,2));
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
- #ifdef DEBUG
- printf("Request to make a new char\n");
- #endif
+ sprintf(tmp_sql, "SELECT `guild_id` FROM `%s` WHERE `master` = '%s'", guild_db, sql_row[0]);
- i = make_new_char_sql(fd, RFIFOP(fd, 2));
+ if (mysql_query(&mysql_handle, tmp_sql) == 0) {
+ sql_res = mysql_store_result(&mysql_handle);
- if (i < 0) {
- WFIFOW(fd, 0) = 0x6e;
- WFIFOB(fd, 2) = 0x00;
- WFIFOSET(fd, 3);
- RFIFOSKIP(fd, 37);
- return 0;
- }
+ if (sql_res != NULL) {
+ if (mysql_num_rows(sql_res) != 0) {
+ sql_row = mysql_fetch_row(sql_res);
- WFIFOW(fd, 0) = 0x6d;
- memset(WFIFOP(fd, 2), 0x00, 106);
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_db, atoi(sql_row[0]));
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
- mmo_char_fromsql(i, char_dat, 0);
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_member_db, atoi(sql_row[0]));
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
- i = 0;
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_castle_db, atoi(sql_row[0]));
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
- WFIFOL(fd, 2) = char_dat[i].char_id;
- WFIFOL(fd,2+4) = char_dat[i].base_exp;
- WFIFOL(fd,2+8) = char_dat[i].zeny;
- WFIFOL(fd,2+12) = char_dat[i].job_exp;
- WFIFOL(fd,2+16) = char_dat[i].job_level;
- WFIFOL(fd,2+28) = char_dat[i].karma;
- WFIFOL(fd,2+32) = char_dat[i].manner;
- WFIFOW(fd,2+40) = 0x30;
- WFIFOW(fd,2+42) = (char_dat[i].hp > 0x7fff) ? 0x7fff : char_dat[i].hp;
- WFIFOW(fd,2+44) = (char_dat[i].max_hp > 0x7fff) ? 0x7fff : char_dat[i].max_hp;
- WFIFOW(fd,2+46) = (char_dat[i].sp > 0x7fff) ? 0x7fff : char_dat[i].sp;
- WFIFOW(fd,2+48) = (char_dat[i].max_sp > 0x7fff) ? 0x7fff : char_dat[i].max_sp;
- WFIFOW(fd,2+50) = DEFAULT_WALK_SPEED; // char_dat[i].speed;
- WFIFOW(fd,2+52) = char_dat[i].class;
- WFIFOW(fd,2+54) = char_dat[i].hair;
- WFIFOW(fd,2+58) = char_dat[i].base_level;
- WFIFOW(fd,2+60) = char_dat[i].skill_point;
- WFIFOW(fd,2+64) = char_dat[i].shield;
- WFIFOW(fd,2+66) = char_dat[i].head_top;
- WFIFOW(fd,2+68) = char_dat[i].head_mid;
- WFIFOW(fd,2+70) = char_dat[i].hair_color;
- memcpy(WFIFOP(fd,2+74), char_dat[i].name, 24);
- WFIFOB(fd,2+98) = char_dat[i].str;
- WFIFOB(fd,2+99) = char_dat[i].agi;
- WFIFOB(fd,2+100) = char_dat[i].vit;
- WFIFOB(fd,2+101) = char_dat[i].int_;
- WFIFOB(fd,2+102) = char_dat[i].dex;
- WFIFOB(fd,2+103) = char_dat[i].luk;
- WFIFOB(fd,2+104) = char_dat[i].char_num;
- WFIFOSET(fd, 108);
-
- RFIFOSKIP(fd, 37);
-
- //to do
- for(ch = 0; ch < 9; ch++) {
- if (sd->found_char[ch] == -1) {
- sd->found_char[ch] = char_dat[i].char_id;
- break;
- }
- }
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_storage_db, atoi(sql_row[0]));
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
- return 0;
-}
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `guild_id` = '%d' OR `alliance_id` = '%d'", guild_alliance_db, atoi(sql_row[0]), atoi(sql_row[0]));
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
-int delete_char(int fd, int len) {
- if (len < 46)
- return -1;
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_position_db, atoi(sql_row[0]));
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
- char email[40];
- int char_id = RFIFOL(fd, 2);
- struct char_session_data *sd = session[fd]->session_data;
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_skill_db, atoi(sql_row[0]));
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
- #ifdef DEBUG
- printf("\033[1;31m Request Char Del:\033[0m \033[1;32m%d\033[0m(\033[1;32m%d\033[0m)\n", sd->account_id, char_id);
- #endif
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_expulsion_db, atoi(sql_row[0]));
+ if (mysql_query(&mysql_handle, tmp_sql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
- memcpy(email, RFIFOP(fd,6), 40);
- sprintf(tmp_sql, "SELECT `email` FROM `%s` WHERE `%s`='%d'",login_db, login_db_account_id, sd->account_id);
- sql_query(tmp_sql,"delete_char");
+ mysql_free_result(sql_res);
+ }
+ } else {
+ if (mysql_errno(&mysql_handle) != 0) {
+ printf("Database server error: %s\n", mysql_error(&mysql_handle));
+ }
+ }
+ } else {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ }
- if ((sql_res = mysql_store_result(&mysql_handle)) &&(sql_row = mysql_fetch_row(sql_res))) {
- if (strcmp(email,sql_row[0]) == 0) {
- mysql_free_result(sql_res);
- } else {
- WFIFOW(fd, 0) = 0x70;
- WFIFOB(fd, 2) = 0;
- WFIFOSET(fd, 3);
+ for(i = 0; i < 9; i++) {
+ printf("char comp: %d - %d (%d)\n", sd->found_char[i], RFIFOL(fd, 2), sd->account_id);
+ if (sd->found_char[i] == RFIFOL(fd, 2)) {
+ for(ch = i; ch < 9-1; ch++)
+ sd->found_char[ch] = sd->found_char[ch+1];
+ sd->found_char[8] = -1;
+ break;
+ }
+ }
+ if (i == 9) { // reject
+ WFIFOW(fd, 0) = 0x70;
+ WFIFOB(fd, 2) = 0;
+ WFIFOSET(fd, 3);
+ } else { // deleted!
+ WFIFOW(fd, 0) = 0x6f;
+ WFIFOSET(fd, 2);
+ }
RFIFOSKIP(fd, 46);
- mysql_free_result(sql_res);
- return 0;
- }
- } else {
- WFIFOW(fd, 0) = 0x70;
- WFIFOB(fd, 2) = 0;
- WFIFOSET(fd, 3);
- RFIFOSKIP(fd, 46);
- mysql_free_result(sql_res);
- return 0;
- }
-
- sprintf(tmp_sql, "SELECT `partner_id` FROM `%s` WHERE `char_id`='%d'",char_db, char_id);
- sql_query(tmp_sql,"delete_char");
-
- if ((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res))) {
- sprintf(tmp_sql,"DELETE FROM `%s` WHERE `char_id`='%d'",char_db, char_id);
- sql_query(tmp_sql,"delete_char");
-
- if (sql_row[0] != 0) {
- char buf[16];
- WBUFW(buf,0) = 0x2b12;
- WBUFL(buf,2) = char_id;
- WBUFL(buf,6) = atoi(sql_row[1]);
- mapif_sendall(buf,10);
- }
- }
-
- mysql_free_result(sql_res);
-
- WFIFOW(fd, 0) = 0x6f;
- WFIFOSET(fd, 2);
-
- RFIFOSKIP(fd, 46);
-
- return 0;
-}
-
-int mapserver_login(int fd, int len) {
- if (len < 60)
- return -1;
-
- int i;
-
- WFIFOW(fd, 0) = 0x2af9;
-
- for(i = 0; i < MAX_MAP_SERVERS; i++) {
- if (server_fd[i] < 0)
break;
- }
-
- if (i == MAX_MAP_SERVERS || strcmp(RFIFOP(fd,2), userid) || strcmp(RFIFOP(fd,26), passwd)) {
- WFIFOB(fd,2) = 3;
- WFIFOSET(fd, 3);
- } else {
- WFIFOB(fd,2) = 0;
- WFIFOSET(fd, 3);
- session[fd]->func_parse = parse_frommap;
- server_fd[i] = fd;
- if(anti_freeze_enable)
- server_freezeflag[i] = 5; // Map anti-freeze system. Counter. 5 ok, 4...0 freezed
- server[i].ip = RFIFOL(fd, 54);
- server[i].port = RFIFOW(fd, 58);
- server[i].users = 0;
- memset(server[i].map, 0, sizeof(server[i].map));
- realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
- char_mapif_init(fd);
- }
-
- RFIFOSKIP(fd,60);
-
- return 0;
-}
-
-int skip_packet(int fd, int len, int real_len) {
- if (len < real_len)
- return 0;
-
- RFIFOSKIP(fd,real_len);
-
- return 0;
-}
-int get_info(int fd, int len) {
- // Athena info get
- WFIFOW(fd, 0) = 0x7531;
- WFIFOB(fd, 2) = ATHENA_MAJOR_VERSION;
- WFIFOB(fd, 3) = ATHENA_MINOR_VERSION;
- WFIFOB(fd, 4) = ATHENA_REVISION;
- WFIFOB(fd, 5) = ATHENA_RELEASE_FLAG;
- WFIFOB(fd, 6) = ATHENA_OFFICIAL_FLAG;
- WFIFOB(fd, 7) = ATHENA_SERVER_INTER | ATHENA_SERVER_CHAR;
- WFIFOW(fd, 8) = ATHENA_MOD_VERSION;
- WFIFOSET(fd, 10);
- RFIFOSKIP(fd, 2);
-
- return 0;
-}
-
-int parse_char(int fd) {
- int len,res=0;
- unsigned short cmd;
- unsigned char *ip = (unsigned char *) &session[fd]->client_addr.sin_addr;
- struct char_session_data *sd = session[fd]->session_data;
-
- if(login_fd < 0)
- session[fd]->eof = 1;
-
- if(session[fd]->eof) {
- if (fd == login_fd)
- login_fd = -1;
- close(fd);
- delete_session(fd);
- return 0;
- }
-
- len = RFIFOREST(fd);
-
- while(len >= 2 && res == 0) {
-
- cmd = RFIFOW(fd,0);
-
- // crc32‚̃XƒLƒbƒv—p
- if( sd==NULL && // –¢ƒƒOƒCƒ“orŠÇ—ƒpƒPƒbƒg
- RFIFOREST(fd)>=4 && // Å’áƒoƒCƒg”§ŒÀ • 0x7530,0x7532ŠÇ—ƒpƒPœ‹Ž
- RFIFOREST(fd)<=21 && // Å‘åƒoƒCƒg”§ŒÀ • ƒT[ƒo[ƒƒOƒCƒ“œ‹Ž
- cmd!=0x20b && // md5’Ê’mƒpƒPƒbƒgœ‹Ž
- (RFIFOREST(fd)<6 || RFIFOW(fd,4)==0x65) ){ // ŽŸ‚ɉ½‚©ƒpƒPƒbƒg‚ª—ˆ‚Ä‚é‚È‚çAÚ‘±‚łȂ¢‚Æ‚¾‚ß
- RFIFOSKIP(fd,4);
- cmd = RFIFOW(fd,0);
- printf("parse_char : %d crc32 skipped\n",fd);
- if(RFIFOREST(fd)==0)
+ case 0x2af8: // login as map-server
+ if (RFIFOREST(fd) < 60)
return 0;
- }
-
-// if(cmd<30000 && cmd!=0x187)
-// printf("parse_char : %d %d %d\n",fd,RFIFOREST(fd),cmd);
-
- // •s³ƒpƒPƒbƒg‚̈—
-// if (sd == NULL && cmd != 0x65 && cmd != 0x20b && cmd != 0x187 &&
-// cmd != 0x2af8 && cmd != 0x7530 && cmd != 0x7532)
-// cmd = 0xffff; // ƒpƒPƒbƒgƒ_ƒ“ƒv‚ð•\ަ‚³‚¹‚é
+ WFIFOW(fd, 0) = 0x2af9;
+ for(i = 0; i < MAX_MAP_SERVERS; i++) {
+ if (server_fd[i] < 0)
+ break;
+ }
+ if (i == MAX_MAP_SERVERS || strcmp((const char*)RFIFOP(fd,2), userid) || strcmp((const char*)RFIFOP(fd,26), passwd)) {
+ WFIFOB(fd,2) = 3;
+ WFIFOSET(fd, 3);
+ } else {
+// int len;
+ WFIFOB(fd,2) = 0;
+ WFIFOSET(fd, 3);
+ session[fd]->func_parse = parse_frommap;
+ server_fd[i] = fd;
+ server[i].ip = RFIFOL(fd, 54);
+ server[i].port = RFIFOW(fd, 58);
+ server[i].users = 0;
+ memset(server[i].map, 0, sizeof(server[i].map));
+ realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
+ char_mapif_init(fd);
+ // send gm acccounts level to map-servers
+/* removed by CLOWNISIUS due to isGM
+ len = 4;
+ WFIFOW(fd,0) = 0x2b15;
+ for(i = 0; i < GM_num; i++) {
+ WFIFOL(fd,len) = gm_account[i].account_id;
+ WFIFOB(fd,len+4) = (unsigned char)gm_account[i].level;
+ len += 5;
+ }
+ WFIFOW(fd,2) = len;
+ WFIFOSET(fd,len);*/
+ }
+ RFIFOSKIP(fd,60);
+ break;
- switch(cmd){
- //20040622 encryption ragexe correspondence
- case 0x20b: res = skip_packet(fd,len,19); break;
+ case 0x187: // Alive?
+ if (RFIFOREST(fd) < 6) {
+ return 0;
+ }
+ RFIFOSKIP(fd, 6);
+ break;
- case 0x65: res = client_request_connect(fd,len); break;
- case 0x66: res = char_select(fd,len,ip); break;
- case 0x67: res = make_new_char(fd,len); break;
- case 0x68: res = delete_char(fd,len); break;
- case 0x2af8: res = mapserver_login(fd,len); break;
- case 0x187: res = skip_packet(fd,len,6); break;
- case 0x7530: res = get_info(fd,len); break;
+ case 0x7530: // Athena info get
+ WFIFOW(fd, 0) = 0x7531;
+ WFIFOB(fd, 2) = ATHENA_MAJOR_VERSION;
+ WFIFOB(fd, 3) = ATHENA_MINOR_VERSION;
+ WFIFOB(fd, 4) = ATHENA_REVISION;
+ WFIFOB(fd, 5) = ATHENA_RELEASE_FLAG;
+ WFIFOB(fd, 6) = ATHENA_OFFICIAL_FLAG;
+ WFIFOB(fd, 7) = ATHENA_SERVER_INTER | ATHENA_SERVER_CHAR;
+ WFIFOW(fd, 8) = ATHENA_MOD_VERSION;
+ WFIFOSET(fd, 10);
+ RFIFOSKIP(fd, 2);
+ return 0;
case 0x7532: // disconnect(default also disconnect)
default:
session[fd]->eof = 1;
return 0;
}
-
- len = RFIFOREST(fd);
}
RFIFOFLUSH(fd);
@@ -2586,8 +2935,8 @@ int parse_char(int fd) {
int parse_console(char *buf) {
char *type,*command;
- type = (char *)malloc(64);
- command = (char *)malloc(64);
+ type = (char *)aMalloc(64);
+ command = (char *)aMalloc(64);
memset(type,0,64);
memset(command,0,64);
@@ -2599,9 +2948,9 @@ int parse_console(char *buf) {
printf("Type of command: %s || Command: %s \n",type,command);
- if(buf) free(buf);
- if(type) free(type);
- if(command) free(command);
+ if(buf) aFree(buf);
+ if(type) aFree(type);
+ if(command) aFree(command);
return 0;
}
@@ -2612,7 +2961,7 @@ int mapif_sendall(unsigned char *buf, unsigned int len) {
int fd;
c = 0;
- for(i = 0; i < MAX_MAP_SERVERS && i < servers_connected; i++) {
+ for(i = 0; i < MAX_MAP_SERVERS; i++) {
if ((fd = server_fd[i]) >= 0) {
memcpy(WFIFOP(fd,0), buf, len);
WFIFOSET(fd,len);
@@ -2628,7 +2977,7 @@ int mapif_sendallwos(int sfd, unsigned char *buf, unsigned int len) {
int fd;
c = 0;
- for(i=0, c=0;i<MAX_MAP_SERVERS && i < servers_connected;i++){
+ for(i=0, c=0;i<MAX_MAP_SERVERS;i++){
if ((fd = server_fd[i]) >= 0 && fd != sfd) {
memcpy(WFIFOP(fd,0), buf, len);
WFIFOSET(fd, len);
@@ -2643,7 +2992,7 @@ int mapif_send(int fd, unsigned char *buf, unsigned int len) {
int i;
if (fd >= 0) {
- for(i = 0; i < MAX_MAP_SERVERS && i < servers_connected; i++) {
+ for(i = 0; i < MAX_MAP_SERVERS; i++) {
if (fd == server_fd[i]) {
memcpy(WFIFOP(fd,0), buf, len);
WFIFOSET(fd,len);
@@ -2654,6 +3003,24 @@ int mapif_send(int fd, unsigned char *buf, unsigned int len) {
return 0;
}
+int send_users_tologin(int tid, unsigned int tick, int id, int data) {
+ int users = count_users();
+ unsigned char buf[16];
+
+ if (login_fd > 0 && session[login_fd]) {
+ // send number of user to login server
+ WFIFOW(login_fd,0) = 0x2714;
+ WFIFOL(login_fd,2) = users;
+ WFIFOSET(login_fd,6);
+ }
+ // send number of players to all map-servers
+ WBUFW(buf,0) = 0x2b00;
+ WBUFL(buf,2) = users;
+ mapif_sendall(buf, 6);
+
+ return 0;
+}
+
int check_connect_login_server(int tid, unsigned int tick, int id, int data) {
if (login_fd <= 0 || session[login_fd] == NULL) {
printf("Attempt to connect to login-server...\n");
@@ -2737,33 +3104,48 @@ int char_lan_config_read(const char *lancfgName){
return 0;
}
+static int char_db_final(void *key,void *data,va_list ap)
+{
+ struct mmo_charstatus *p = (struct mmo_charstatus *) data;
+ if (p) aFree(p);
+ return 0;
+}
void do_final(void) {
- printf("Closing char-server...\n");
-
+ printf("Doing final stage...\n");
+ //mmo_char_sync();
+ //inter_save();
do_final_itemdb();
-
//check SQL save progress.
//wait until save char complete
- printf("Waiting until char saving complete...\n");
- do {
- sleep (0);
- }while (save_flag != 0);
- sprintf(tmp_sql,"UPDATE `%s` SET `online`='0' WHERE `online`='1'", char_db);
- sql_query(tmp_sql,"do_final");
+ set_all_offline();
+
+ flush_fifos();
sprintf(tmp_sql,"DELETE FROM `ragsrvinfo");
- sql_query(tmp_sql,"do_final");
+ if (mysql_query(&mysql_handle, tmp_sql))
+ printf("DB server Error (insert `char`)- %s\n", mysql_error(&mysql_handle));
+
+ if(gm_account) {
+ aFree(gm_account);
+ gm_account = 0;
+ }
- if(gm_account) free(gm_account);
+ if(char_dat) {
+ aFree(char_dat);
+ char_dat = 0;
+ }
- if(char_dat) free(char_dat);
delete_session(login_fd);
delete_session(char_fd);
+ numdb_final(char_db_, char_db_final);
+ exit_dbn();
mysql_close(&mysql_handle);
+ mysql_close(&lmysql_handle);
+ timer_final();
- printf("Good-bye...\n");
+ printf("ok! all done...\n");
}
void sql_config_read(const char *cfgName){ /* Kalaspuff, to get login_db */
@@ -2828,11 +3210,7 @@ void sql_config_read(const char *cfgName){ /* Kalaspuff, to get login_db */
strcpy(db_path,w2);
//Map server option to use SQL db or not
}else if(strcmpi(w1,"use_sql_db")==0){ // added for sql item_db read for char server [Valaris]
- if (strcmpi(w2, "yes")) {
- db_use_sqldbs = 1;
- } else if (strcmpi(w2, "no")) {
- db_use_sqldbs = 0;
- }
+ db_use_sqldbs = config_switch(w2);
printf("Using SQL dbs: %s\n",w2);
//custom columns for login database
}else if(strcmpi(w1,"login_db_level")==0){
@@ -2846,6 +3224,7 @@ void sql_config_read(const char *cfgName){ /* Kalaspuff, to get login_db */
}else if(strcmpi(w1,"import")==0){
sql_config_read(w2);
}
+
}
fclose(fp);
printf("reading configure done.....\n");
@@ -2869,15 +3248,15 @@ int char_config_read(const char *cfgName) {
if (sscanf(line,"%[^:]: %[^\r\n]", w1, w2) != 2)
continue;
- remove_control_chars(w1);
- remove_control_chars(w2);
+ remove_control_chars((unsigned char *) w1);
+ remove_control_chars((unsigned char *) w2);
if (strcmpi(w1, "userid") == 0) {
memcpy(userid, w2, 24);
} else if (strcmpi(w1, "passwd") == 0) {
memcpy(passwd, w2, 24);
} else if (strcmpi(w1, "server_name") == 0) {
memcpy(server_name, w2, 16);
- printf("%s server has been intialized\n", w2);
+ printf("%s server has been initialized\n", w2);
} else if (strcmpi(w1, "wisp_server_name") == 0) {
if (strlen(w2) >= 4) {
memcpy(wisp_server_name, w2, sizeof(wisp_server_name));
@@ -2901,6 +3280,14 @@ int char_config_read(const char *cfgName) {
sprintf(char_ip_str, "%d.%d.%d.%d", (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
} else
memcpy(char_ip_str, w2, 16);
+ } else if (strcmpi(w1, "bind_ip") == 0) {
+ bind_ip_set_ = 1;
+ h = gethostbyname (w2);
+ if(h != NULL) {
+ printf("Character server binding IP address : %s -> %d.%d.%d.%d\n", w2, (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+ sprintf(bind_ip_str, "%d.%d.%d.%d", (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+ } else
+ memcpy(bind_ip_str, w2, 16);
} else if (strcmpi(w1, "char_port") == 0) {
char_port = atoi(w2);
} else if (strcmpi(w1, "char_maintenance") == 0) {
@@ -2911,6 +3298,10 @@ int char_config_read(const char *cfgName) {
max_connect_user = atoi(w2);
if (max_connect_user < 0)
max_connect_user = 0; // unlimited online players
+ } else if(strcmpi(w1, "gm_allow_level") == 0) {
+ gm_allow_level = atoi(w2);
+ if(gm_allow_level < 0)
+ gm_allow_level = 99;
} else if (strcmpi(w1, "check_ip_flag") == 0) {
check_ip_flag = config_switch(w2);
} else if (strcmpi(w1, "autosave_time") == 0) {
@@ -2960,13 +3351,8 @@ int char_config_read(const char *cfgName) {
strcpy(char_name_letters, w2);
} else if (strcmpi(w1, "check_ip_flag") == 0) {
check_ip_flag = config_switch(w2);
- // anti-freeze options [Valaris]
- } else if(strcmpi(w1,"anti_freeze_enable")==0){
- anti_freeze_enable = config_switch(w2);
- } else if (strcmpi(w1, "anti_freeze_interval") == 0) {
- ANTI_FREEZE_INTERVAL = atoi(w2);
- if (ANTI_FREEZE_INTERVAL < 5)
- ANTI_FREEZE_INTERVAL = 5; // minimum 5 seconds
+ } else if (strcmpi(w1, "chars_per_account") == 0) { //maxchars per account [Sirius]
+ char_per_account = atoi(w2);
} else if (strcmpi(w1, "import") == 0) {
char_config_read(w2);
} else if (strcmpi(w1, "console") == 0) {
@@ -2976,9 +3362,6 @@ int char_config_read(const char *cfgName) {
}
fclose(fp);
-//Read ItemDB
- do_init_itemdb();
-
return 0;
}
@@ -3004,6 +3387,7 @@ int flush_timer(int tid, unsigned int tick, int id, int data){
int do_init(int argc, char **argv){
int i;
+ SERVER_TYPE = SERVER_CHAR;
for(i = 0; i < MAX_MAP_SERVERS; i++) {
memset(&server[i], 0, sizeof(struct mmo_map_server));
server_fd[i] = -1;
@@ -3018,6 +3402,9 @@ int do_init(int argc, char **argv){
inter_init((argc > 2) ? argv[2] : inter_cfgName); // inter server ÃʱâÈ­
printf("interserver configuration reading done.....\n");
+ //Read ItemDB
+ do_init_itemdb();
+
printf("start char server initializing.....\n");
mmo_char_sql_init();
printf("char server initializing done.....\n");
@@ -3028,16 +3415,13 @@ int do_init(int argc, char **argv){
printf("set terminate function -> do_final().....\n");
set_termfunc(do_final);
- printf("open port %d.....\n",char_port);
- char_fd = make_listen_port(char_port);
-
if ((naddr_ != 0) && (login_ip_set_ == 0 || char_ip_set_ == 0)) {
// The char server should know what IP address it is running on
// - MouseJstr
int localaddr = ntohl(addr_[0]);
unsigned char *ptr = (unsigned char *) &localaddr;
char buf[16];
- sprintf(buf, "%d.%d.%d.%d", ptr[0], ptr[1], ptr[2], ptr[3]);;
+ sprintf(buf, "%d.%d.%d.%d", ptr[0], ptr[1], ptr[2], ptr[3]);
if (naddr_ != 1)
printf("Multiple interfaces detected.. using %s as our IP address\n", buf);
else
@@ -3048,21 +3432,31 @@ int do_init(int argc, char **argv){
strcpy(char_ip_str, buf);
if (ptr[0] == 192 && ptr[1] == 168)
- printf("Firewall detected.. edit lan_support.conf and char_athena.conf");
+ printf("Firewall detected.. edit lan_support.conf and char_athena.conf\n");
}
login_ip = inet_addr(login_ip_str);
char_ip = inet_addr(char_ip_str);
+ printf("open port %d.....\n",char_port);
+ //char_fd = make_listen_port(char_port);
+ if (bind_ip_set_)
+ char_fd = make_listen_bind(inet_addr(bind_ip_str),char_port);
+ else
+ char_fd = make_listen_bind(INADDR_ANY,char_port);
+
// send ALIVE PING to login server.
printf("add interval tic (check_connect_login_server)....\n");
i = add_timer_interval(gettick() + 10, check_connect_login_server, 0, 0, 10 * 1000);
+ // send USER COUNT PING to login server.
+ printf("add interval tic (send_users_tologin)....\n");
+ i = add_timer_interval(gettick() + 10, send_users_tologin, 0, 0, 5 * 1000);
+
//no need to set sync timer on SQL version.
//printf("add interval tic (mmo_char_sync_timer)....\n");
//i = add_timer_interval(gettick() + 10, mmo_char_sync_timer, 0, 0, autosave_interval);
- add_timer_func_list(map_anti_freeze_system, "map_anti_freeze_system");
//Added for Mugendais I'm Alive mod
if(imalive_on)
add_timer_interval(gettick()+10, imalive_timer,0,0,imalive_time*1000);
@@ -3071,27 +3465,114 @@ int do_init(int argc, char **argv){
if(flush_on)
add_timer_interval(gettick()+10, flush_timer,0,0,flush_time);
- if(anti_freeze_enable > 0) {
- add_timer_func_list(map_anti_freeze_system, "map_anti_freeze_system");
- i = add_timer_interval(gettick() + 1000, map_anti_freeze_system, 0, 0, ANTI_FREEZE_INTERVAL * 1000); // checks every X seconds user specifies
- }
+ read_gm_account();
if ( console ) {
set_defaultconsoleparse(parse_console);
start_console();
}
+ //Cleaning the tables for NULL entrys @ startup [Sirius]
+ //Chardb clean
+ printf("Cleaning the '%s' table...", char_db);
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `account_id` = '0'", char_db);
+ if(mysql_query(&mysql_handle, tmp_sql)){
+ //error on clean
+ printf(" fail.\n");
+ }else{
+ printf(" done.\n");
+ }
+
+ //guilddb clean
+ printf("Cleaning the '%s' table...", guild_db);
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `guild_lv` = '0' AND `max_member` = '0' AND `exp` = '0' AND `next_exp` = '0' AND `average_lv` = '0'", guild_db);
+ if(mysql_query(&mysql_handle, tmp_sql)){
+ //error on clean
+ printf(" fail.\n");
+ }else{
+ printf(" done.\n");
+ }
+
+ //guildmemberdb clean
+ printf("Cleaning the '%s' table...", guild_member_db);
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `guild_id` = '0' AND `account_id` = '0' AND `char_id` = '0'", guild_member_db);
+ if(mysql_query(&mysql_handle, tmp_sql)){
+ //error on clean
+ printf(" fail.\n");
+ }else{
+ printf(" done.\n");
+ }
+
+
+
printf("char server init func end (now unlimited loop start!)....\n");
printf("The char-server is \033[1;32mready\033[0m (Server is listening on the port %d).\n\n", char_port);
return 0;
}
-
#undef mysql_query
-int STDCALL mysql_query(MYSQL *mysql, const char *q);
int debug_mysql_query(char *file, int line, void *mysql, const char *q) {
+#ifdef TWILIGHT
printf("sql: %s:%d# %s\n", file, line, q);
+#endif
return mysql_query((MYSQL *) mysql, q);
}
+int char_child(int parent_id, int child_id) {
+ int tmp_id = 0;
+ sprintf (tmp_sql, "SELECT `child` FROM `%s` WHERE `char_id` = '%d'", char_db, parent_id);
+ if (mysql_query (&mysql_handle, tmp_sql)) {
+ printf ("DB server Error (select `char2`)- %s\n", mysql_error (&mysql_handle));
+ }
+ sql_res = mysql_store_result (&mysql_handle);
+ if (sql_res) {
+ sql_row = mysql_fetch_row (sql_res);
+ tmp_id = atoi (sql_row[0]);
+ mysql_free_result (sql_res);
+ }
+ else
+ printf("CHAR: child Failed!\n");
+ if ( tmp_id == child_id )
+ return 1;
+ else
+ return 0;
+}
+
+int char_married(int pl1,int pl2) {
+ int tmp_id = 0;
+ sprintf (tmp_sql, "SELECT `partner_id` FROM `%s` WHERE `char_id` = '%d'", char_db, pl1);
+ if (mysql_query (&mysql_handle, tmp_sql)) {
+ printf ("DB server Error (select `char2`)- %s\n", mysql_error (&mysql_handle));
+ }
+ sql_res = mysql_store_result (&mysql_handle);
+ if (sql_res) {
+ sql_row = mysql_fetch_row (sql_res);
+ tmp_id = atoi (sql_row[0]);
+ mysql_free_result (sql_res);
+ }
+ else
+ printf("CHAR: married Failed!\n");
+ if ( tmp_id == pl2 )
+ return 1;
+ else
+ return 0;
+}
+
+int char_nick2id (char *name) {
+ int char_id = 0;
+ sprintf (tmp_sql, "SELECT `char_id` FROM `%s` WHERE `name` = '%s'", char_db, name);
+ if (mysql_query (&mysql_handle, tmp_sql)) {
+ printf ("DB server Error (select `char2`)- %s\n", mysql_error (&mysql_handle));
+ }
+ sql_res = mysql_store_result (&mysql_handle);
+ if (sql_res) {
+ sql_row = mysql_fetch_row (sql_res);
+ char_id = atoi (sql_row[0]);
+ mysql_free_result (sql_res);
+ }
+ else
+ printf ("CHAR: nick2id Failed!\n");
+ return char_id;
+}
+
diff --git a/src/char_sql/char.h b/src/char_sql/char.h
index 8da399eff..6ade96c36 100644
--- a/src/char_sql/char.h
+++ b/src/char_sql/char.h
@@ -40,12 +40,15 @@ enum {
struct itemtemp{
struct itemtmp equip[MAX_GUILD_STORAGE],notequip[MAX_GUILD_STORAGE];
};
-int memitemdata_to_sql(struct itemtemp mapitem, int eqcount, int noteqcount, int char_id,int tableswitch);
-int memitemdata_to_sql2(struct itemtemp mapitem, int eqcount, int char_id,int tableswitch);
+int memitemdata_to_sql(struct itemtmp mapitem[], int count, int char_id,int tableswitch);
int mapif_sendall(unsigned char *buf,unsigned int len);
int mapif_sendallwos(int fd,unsigned char *buf,unsigned int len);
int mapif_send(int fd,unsigned char *buf,unsigned int len);
+int char_nick2id (char *name);
+int char_married(int pl1,int pl2);
+int char_child(int parent_id, int child_id);
+
extern int autosave_interval;
extern char db_path[];
extern char char_db[256];
@@ -68,11 +71,13 @@ extern char guild_storage_db[256];
extern char party_db[256];
extern char pet_db[256];
-int db_use_sqldbs; // added for sql item_db read for char server [Valaris]
+extern int db_use_sqldbs; // added for sql item_db read for char server [Valaris]
extern char login_db_level[32];
extern char login_db_account_id[32];
extern int lowest_gm_level;
+extern int GM_num;
+extern struct gm_account *gm_account;
extern int debug_mysql_query(char *file, int line, void *mysql, const char *q);
diff --git a/src/char_sql/int_guild.c b/src/char_sql/int_guild.c
index a850bc0f5..794f2e01f 100644
--- a/src/char_sql/int_guild.c
+++ b/src/char_sql/int_guild.c
@@ -3,8 +3,12 @@
// SQL conversion by hack
//
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
#include "char.h"
-#include "strlib.h"
+#include "../common/strlib.h"
#include "int_storage.h"
#include "inter.h"
#include "int_guild.h"
@@ -12,17 +16,10 @@
#include "mmo.h"
#include "socket.h"
#include "db.h"
-#include "utils.h"
-
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include "malloc.h"
static struct dbt *guild_db_;
static struct dbt *castle_db_;
-static struct dbt *guild_expcache_db_;
-static struct dbt *guild_infoevent_db_;
-static struct dbt *guild_castleinfoevent_db_;
static struct guild *guild_pt;
static struct guild *guild_pt2;
@@ -39,6 +36,18 @@ int mapif_guild_basicinfochanged(int guild_id,int type,const void *data,int len)
int mapif_guild_info(int fd,struct guild *g);
int guild_break_sub(void *key,void *data,va_list ap);
+#define mysql_query(_x, _y) debug_mysql_query(__FILE__, __LINE__, _x, _y)
+
+static int _erase_guild(void *key, void *data, va_list ap) {
+ int guild = va_arg(ap, int);
+ struct guild_castle * castle = (struct guild_castle *) data;
+ if (castle->guild_id == guild) {
+ aFree(castle);
+ db_erase(castle_db_, key);
+ }
+
+ return 0;
+}
// Save guild into sql
int inter_guild_tosql(struct guild *g,int flag)
@@ -47,67 +56,114 @@ int inter_guild_tosql(struct guild *g,int flag)
// 2 `guild_member` (`guild_id`,`account_id`,`char_id`,`hair`,`hair_color`,`gender`,`class`,`lv`,`exp`,`exp_payper`,`online`,`position`,`rsv1`,`rsv2`,`name`)
// 4 `guild_position` (`guild_id`,`position`,`name`,`mode`,`exp_mode`)
// 8 `guild_alliance` (`guild_id`,`opposition`,`alliance_id`,`name`)
- // 16 `guild_expulsion` (`guild_id`,`name`,`mes`,`acc`,`account_id`,`rsv1`,`rsv2`,`rsv3`)
+ // 16 `guild_expulsion` (`guild_id`,`name`,`mes`,`acc`,`account_id`,`rsv1`,`rsv2`,`rsv3`)
// 32 `guild_skill` (`guild_id`,`id`,`lv`)
-
- char t_name[100],t_master[24],t_mes1[60],t_mes2[120],t_member[24],t_position[24],t_alliance[24]; // temporay storage for str convertion;
+
+ char t_name[100],t_master[24],t_mes1[60],t_mes2[240],t_member[24],t_position[24],t_alliance[24]; // temporay storage for str convertion;
char t_ename[24],t_emes[40];
char emblem_data[4096];
- int first = 1, i=0;
- int guild_member=0,guild_online_member=0;
- struct StringBuf sbuf;
+ int i=0;
+ int guild_exist=0,guild_member=0,guild_online_member=0;
- StringBuf_Init(&sbuf);
-
if (g->guild_id<=0) return -1;
-
- printf("(\033[1;35m%d\033[0m) Request save guild - ",g->guild_id);
-
+
+ printf("(\033[1;35m%d\033[0m) Request save guild -(flag 0x%x) ",g->guild_id, flag);
+
jstrescapecpy(t_name, g->name);
-
- guild_member = 0;
- i = 0;
- while (i<g->max_member) {
- if (g->member[i].account_id>0) guild_member++;
- i++;
+
+ //printf("- Check if guild %d exists\n",g->guild_id);
+ sprintf(tmp_sql, "SELECT count(*) FROM `%s` WHERE `guild_id`='%d'",guild_db,g->guild_id);
+ if(mysql_query(&mysql_handle, tmp_sql) ) {
+ printf("DB server Error (delete `guild`)- %s\n", mysql_error(&mysql_handle) );
+ }
+ sql_res = mysql_store_result(&mysql_handle) ;
+ if (sql_res!=NULL && mysql_num_rows(sql_res)>0) {
+ sql_row = mysql_fetch_row(sql_res);
+ guild_exist = atoi (sql_row[0]);
+ //printf("- Check if guild %d exists : %s\n",g->guild_id,((guild_exist==0)?"No":"Yes"));
+ }
+ mysql_free_result(sql_res) ; //resource free
+
+ if (guild_exist >0){
+ // Check members in party
+ sprintf(tmp_sql,"SELECT count(*) FROM `%s` WHERE `guild_id`='%d'",guild_member_db, g->guild_id);
+ if(mysql_query(&mysql_handle, tmp_sql) ) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
+ return -1;
}
-
+ sql_res = mysql_store_result(&mysql_handle) ;
+ if (sql_res!=NULL && mysql_num_rows(sql_res)>0) {
+ sql_row = mysql_fetch_row(sql_res);
+
+ guild_member = atoi (sql_row[0]);
+ // printf("- Check members in guild %d : %d \n",g->guild_id,guild_member);
+
+ }
+ mysql_free_result(sql_res) ; //resource free
+
// Delete old guild from sql
if (flag&1||guild_member==0){
- StringBuf_Printf(&sbuf, "DELETE FROM `%s` WHERE `guild_id`='%d';\n",guild_db, g->guild_id);
+ // printf("- Delete guild %d from guild\n",g->guild_id);
+ sprintf(tmp_sql, "DELETE FROM `%s` WHERE `guild_id`='%d'",guild_db, g->guild_id);
+ if(mysql_query(&mysql_handle, tmp_sql) ) {
+ printf("DB server Error (delete `guild`)- %s\n", mysql_error(&mysql_handle) );
+ }
}
if (flag&2||guild_member==0){
// printf("- Delete guild %d from guild_member\n",g->guild_id);
- StringBuf_Printf(&sbuf, "DELETE FROM `%s` WHERE `guild_id`='%d';\n",guild_member_db, g->guild_id);
- StringBuf_Printf(&sbuf, "UPDATE `%s` SET `guild_id`='0' WHERE `guild_id`='%d';\n",char_db, g->guild_id);
+ sprintf(tmp_sql, "DELETE FROM `%s` WHERE `guild_id`='%d'",guild_member_db, g->guild_id);
+ if(mysql_query(&mysql_handle, tmp_sql) ) {
+ printf("DB server Error (delete `guild_member`)- %s\n", mysql_error(&mysql_handle) );
+ }
+ sprintf(tmp_sql, "UPDATE `%s` SET `guild_id`='0' WHERE `guild_id`='%d'",char_db, g->guild_id);
+ if(mysql_query(&mysql_handle, tmp_sql) ) {
+ printf("DB server Error (update `char`)- %s\n", mysql_error(&mysql_handle) );
+ }
}
if (flag&32||guild_member==0){
// printf("- Delete guild %d from guild_skill\n",g->guild_id);
- StringBuf_Printf(&sbuf, "DELETE FROM `%s` WHERE `guild_id`='%d';\n",guild_skill_db, g->guild_id);
+ sprintf(tmp_sql, "DELETE FROM `%s` WHERE `guild_id`='%d'",guild_skill_db, g->guild_id);
+ if(mysql_query(&mysql_handle, tmp_sql) ) {
+ printf("DB server Error (delete `guild_skill`)- %s\n", mysql_error(&mysql_handle) );
+ }
}
if (flag&4||guild_member==0){
// printf("- Delete guild %d from guild_position\n",g->guild_id);
- StringBuf_Printf(&sbuf, "DELETE FROM `%s` WHERE `guild_id`='%d';\n",guild_position_db, g->guild_id);
+ sprintf(tmp_sql, "DELETE FROM `%s` WHERE `guild_id`='%d'",guild_position_db, g->guild_id);
+ if(mysql_query(&mysql_handle, tmp_sql) ) {
+ printf("DB server Error (delete `guild_position`)- %s\n", mysql_error(&mysql_handle) );
+ }
}
if (flag&16||guild_member==0){
// printf("- Delete guild %d from guild_expulsion\n",g->guild_id);
- StringBuf_Printf(&sbuf, "DELETE FROM `%s` WHERE `guild_id`='%d';\n",guild_expulsion_db, g->guild_id);
+ sprintf(tmp_sql, "DELETE FROM `%s` WHERE `guild_id`='%d'",guild_expulsion_db, g->guild_id);
+ if(mysql_query(&mysql_handle, tmp_sql) ) {
+ printf("DB server Error (delete `guild_expulsion`)- %s\n", mysql_error(&mysql_handle) );
+ }
}
if (flag&8||guild_member==0){
// printf("- Delete guild %d from guild_alliance\n",g->guild_id);
- StringBuf_Printf(&sbuf, "DELETE FROM `%s` WHERE `guild_id`='%d' OR `alliance_id`='%d';\n",guild_alliance_db, g->guild_id,g->guild_id);
+ sprintf(tmp_sql, "DELETE FROM `%s` WHERE `guild_id`='%d' OR `alliance_id`='%d'",guild_alliance_db, g->guild_id,g->guild_id);
+ if(mysql_query(&mysql_handle, tmp_sql) ) {
+ printf("DB server Error (delete `guild_alliance`)- %s\n", mysql_error(&mysql_handle) );
+ }
}
if (flag&2||guild_member==0){
// printf("- Delete guild %d from char\n",g->guild_id);
- StringBuf_Printf(&sbuf, "UPDATE `%s` SET `guild_id`='0' WHERE `guild_id`='%d';\n",char_db, g->guild_id);
+ sprintf(tmp_sql, "UPDATE `%s` SET `guild_id`='0' WHERE `guild_id`='%d'",char_db, g->guild_id);
+ if(mysql_query(&mysql_handle, tmp_sql) ) {
+ printf("DB server Error (delete `guild_alliance`)- %s\n", mysql_error(&mysql_handle) );
+ }
}
if (guild_member==0){
// printf("- Delete guild %d from guild_castle\n",g->guild_id);
- StringBuf_Printf(&sbuf, "DELETE FROM `%s` WHERE `guild_id`='%d';\n",guild_castle_db, g->guild_id);
+ sprintf(tmp_sql, "DELETE FROM `%s` WHERE `guild_id`='%d'",guild_castle_db, g->guild_id);
+ if(mysql_query(&mysql_handle, tmp_sql) ) {
+ printf("DB server Error (delete `guild_castle`)- %s\n", mysql_error(&mysql_handle) );
+ }
+ db_foreach(castle_db_, _erase_guild, g->guild_id);
}
-#if 0
}
-#endif
guild_online_member = 0;
i=0;
@@ -115,13 +171,11 @@ int inter_guild_tosql(struct guild *g,int flag)
if (g->member[i].account_id>0) guild_online_member++;
i++;
}
-
+
// No member in guild , no need to create it in sql
if (guild_member <= 0 && guild_online_member <=0) {
inter_guild_storage_delete(g->guild_id);
printf("No member in guild %d , break it! \n",g->guild_id);
- if(mysql_query(&mysql_handle, StringBuf_Value(&sbuf)) )
- printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
return -2;
}
@@ -132,134 +186,131 @@ int inter_guild_tosql(struct guild *g,int flag)
for(i=0;i<g->emblem_len;i++){
len+=sprintf(emblem_data+len,"%02x",(unsigned char)(g->emblem_data[i]));
//printf("%02x",(unsigned char)(g->emblem_data[i]));
- }
+ }
emblem_data[len] = '\0';
//printf("- emblem_len = %d \n",g->emblem_len);
- StringBuf_Printf(&sbuf, "INSERT INTO `%s` "
+ sprintf(tmp_sql,"INSERT INTO `%s` "
"(`guild_id`, `name`,`master`,`guild_lv`,`connect_member`,`max_member`,`average_lv`,`exp`,`next_exp`,`skill_point`,`castle_id`,`mes1`,`mes2`,`emblem_len`,`emblem_id`,`emblem_data`) "
- "VALUES ('%d', '%s', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s', '%s', '%d', '%d', '%s');",
+ "VALUES ('%d', '%s', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s', '%s', '%d', '%d', '%s')",
guild_db, g->guild_id,t_name,jstrescapecpy(t_master,g->master),
g->guild_lv,g->connect_member,g->max_member,g->average_lv,g->exp,g->next_exp,g->skill_point,g->castle_id,
jstrescapecpy(t_mes1,g->mes1),jstrescapecpy(t_mes2,g->mes2),g->emblem_len,g->emblem_id,emblem_data);
//printf(" %s\n",tmp_sql);
+ if(mysql_query(&mysql_handle, tmp_sql) ) {
+ printf("DB server Error (insert `guild`)- %s\n", mysql_error(&mysql_handle) );
+ }
}
if (flag&2||guild_member==0){
- struct StringBuf sbuf2;
- StringBuf_Init(&sbuf2);
-
- first = 1;
-
- StringBuf_Printf(&sbuf,"REPLACE `%s` (`guild_id`,`account_id`,`char_id`,`hair`,`hair_color`,`gender`,`class`,`lv`,`exp`,`exp_payper`,`online`,`position`,`rsv1`,`rsv2`,`name`) VALUES \n", guild_member_db);
-
- StringBuf_Printf(&sbuf2, "UPDATE `%s` SET `guild_id`='%d' WHERE `char_id` IN (",char_db, g->guild_id);
-
- //printf("- Insert guild %d to guild_member\n",g->guild_id);
- for(i=0;i<g->max_member;i++){
- if (g->member[i].account_id>0){
- struct guild_member *m = &g->member[i];
- if (first == 0) {
- StringBuf_Printf(&sbuf , ", ");
- StringBuf_Printf(&sbuf2, ", ");
- } else
- first = 0;
- StringBuf_Printf(&sbuf, "('%d','%d','%d','%d','%d', '%d','%d','%d','%d','%d','%d','%d','%d','%d','%s')\n",
- g->guild_id,
- m->account_id,m->char_id,
- m->hair,m->hair_color,m->gender,
- m->class,m->lv,m->exp,m->exp_payper,m->online,m->position,
- 0,0,
- jstrescapecpy(t_member,m->name));
-
- StringBuf_Printf(&sbuf2, "'%d'", m->char_id);
- }
- }
- StringBuf_Printf(&sbuf, ";\n");
- StringBuf_Printf(&sbuf2,");\n");
- StringBuf_Append(&sbuf, &sbuf2);
- StringBuf_Destroy(&sbuf2);
+ struct StringBuf sbuf;
+ struct StringBuf sbuf2;
+ int first = 1;
+ StringBuf_Init(&sbuf2);
+ StringBuf_Init(&sbuf);
+
+ StringBuf_Printf(&sbuf,"REPLACE `%s` (`guild_id`,`account_id`,`char_id`,`hair`,`hair_color`,`gender`,`class`,`lv`,`exp`,`exp_payper`,`online`,`position`,`rsv1`,`rsv2`,`name`) VALUES \n", guild_member_db);
+
+ StringBuf_Printf(&sbuf2, "UPDATE `%s` SET `guild_id`='%d' WHERE `char_id` IN (",char_db, g->guild_id);
+
+ //printf("- Insert guild %d to guild_member\n",g->guild_id);
+ for(i=0;i<g->max_member;i++){
+ if (g->member[i].account_id>0){
+ struct guild_member *m = &g->member[i];
+ if (first == 0) {
+ StringBuf_Printf(&sbuf , ", ");
+ StringBuf_Printf(&sbuf2, ", ");
+ } else
+ first = 0;
+ StringBuf_Printf(&sbuf, "('%d','%d','%d','%d','%d', '%d','%d','%d','%d','%d','%d','%d','%d','%d','%s')\n",
+ g->guild_id,
+ m->account_id,m->char_id,
+ m->hair,m->hair_color,m->gender,
+ m->class_,m->lv,m->exp,m->exp_payper,m->online,m->position,
+ 0,0,
+ jstrescapecpy(t_member,m->name));
+
+ StringBuf_Printf(&sbuf2, "'%d'", m->char_id);
+ }
+ }
+ StringBuf_Printf(&sbuf2,")");
+
+ if(mysql_query(&mysql_handle, StringBuf_Value(&sbuf)))
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
+
+ if(mysql_query(&mysql_handle, StringBuf_Value(&sbuf2)))
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
+
+ StringBuf_Destroy(&sbuf2);
+ StringBuf_Destroy(&sbuf);
}
-
+
if (flag&4||guild_member==0){
- first = 1;
//printf("- Insert guild %d to guild_position\n",g->guild_id);
- StringBuf_Printf(&sbuf ,"INSERT INTO `%s` (`guild_id`,`position`,`name`,`mode`,`exp_mode`) VALUES ", guild_position_db);
for(i=0;i<MAX_GUILDPOSITION;i++){
- if (first == 0)
- StringBuf_Printf(&sbuf , ", ");
- else
- first = 0;
struct guild_position *p = &g->position[i];
- StringBuf_Printf(&sbuf , "('%d','%d', '%s','%d','%d')",
- g->guild_id, i, jstrescapecpy(t_position,p->name),p->mode,p->exp_mode);
+ sprintf(tmp_sql,"INSERT INTO `%s` (`guild_id`,`position`,`name`,`mode`,`exp_mode`) VALUES ('%d','%d', '%s','%d','%d')",
+ guild_position_db, g->guild_id, i, jstrescapecpy(t_position,p->name),p->mode,p->exp_mode);
+ //printf(" %s\n",tmp_sql);
+ if(mysql_query(&mysql_handle, tmp_sql) ) {
+ printf("DB server Error (insert `guild_position`)- %s\n", mysql_error(&mysql_handle) );
+ }
}
- StringBuf_Printf(&sbuf ,";\n");
}
if (flag&8||guild_member==0){
- first = 1;
- StringBuf_Printf(&sbuf , "INSERT INTO `%s` (`guild_id`,`opposition`,`alliance_id`,`name`) VALUES ", guild_alliance_db);
//printf("- Insert guild %d to guild_alliance\n",g->guild_id);
for(i=0;i<MAX_GUILDALLIANCE;i++){
struct guild_alliance *a=&g->alliance[i];
if(a->guild_id>0){
- if (first == 0)
- StringBuf_Printf(&sbuf , ", ");
- else
- first = 0;
- StringBuf_Printf(&sbuf , "('%d','%d','%d','%s')",
- g->guild_id,a->opposition,a->guild_id,jstrescapecpy(t_alliance,a->name));
-
- StringBuf_Printf(&sbuf , ", ('%d','%d','%d','%s')",
- a->guild_id,a->opposition,g->guild_id,t_name);
+ sprintf(tmp_sql,"INSERT INTO `%s` (`guild_id`,`opposition`,`alliance_id`,`name`) "
+ "VALUES ('%d','%d','%d','%s')",
+ guild_alliance_db, g->guild_id,a->opposition,a->guild_id,jstrescapecpy(t_alliance,a->name));
//printf(" %s\n",tmp_sql);
+ if(mysql_query(&mysql_handle, tmp_sql) ) {
+ printf("DB server Error (insert `guild_alliance`)- %s\n", mysql_error(&mysql_handle) );
+ }
+ sprintf(tmp_sql,"INSERT INTO `%s` (`guild_id`,`opposition`,`alliance_id`,`name`) "
+ "VALUES ('%d','%d','%d','%s')",
+ guild_alliance_db, a->guild_id,a->opposition,g->guild_id,t_name);
+ //printf(" %s\n",tmp_sql);
+ if(mysql_query(&mysql_handle, tmp_sql) ) {
+ printf("DB server Error (insert `guild_alliance`)- %s\n", mysql_error(&mysql_handle) );
+ }
}
}
- StringBuf_Printf(&sbuf ,";\n");
}
if (flag&16||guild_member==0){
- first = 1;
//printf("- Insert guild %d to guild_expulsion\n",g->guild_id);
- StringBuf_Printf(&sbuf, "INSERT INTO `%s` (`guild_id`,`name`,`mes`,`acc`,`account_id`,`rsv1`,`rsv2`,`rsv3`) VALUES ",
- guild_expulsion_db);
for(i=0;i<MAX_GUILDEXPLUSION;i++){
struct guild_explusion *e=&g->explusion[i];
if(e->account_id>0){
- if (first == 0)
- StringBuf_Printf(&sbuf , ", ");
- else
- first = 0;
- StringBuf_Printf(&sbuf, "('%d','%s','%s','%s','%d','%d','%d','%d')",
- g->guild_id, jstrescapecpy(t_ename,e->name),jstrescapecpy(t_emes,e->mes),e->acc,e->account_id,e->rsv1,e->rsv2,e->rsv3 );
+ sprintf(tmp_sql,"INSERT INTO `%s` (`guild_id`,`name`,`mes`,`acc`,`account_id`,`rsv1`,`rsv2`,`rsv3`) "
+ "VALUES ('%d','%s','%s','%s','%d','%d','%d','%d')",
+ guild_expulsion_db, g->guild_id,
+ jstrescapecpy(t_ename,e->name),jstrescapecpy(t_emes,e->mes),e->acc,e->account_id,e->rsv1,e->rsv2,e->rsv3 );
//printf(" %s\n",tmp_sql);
+ if(mysql_query(&mysql_handle, tmp_sql) ) {
+ printf("DB server Error (insert `guild_expulsion`)- %s\n", mysql_error(&mysql_handle) );
+ }
}
}
- StringBuf_Printf(&sbuf ,";\n");
}
if (flag&32||guild_member==0){
- first = 1;
//printf("- Insert guild %d to guild_skill\n",g->guild_id);
- StringBuf_Printf(&sbuf,"INSERT INTO `%s` (`guild_id`,`id`,`lv`) VALUES ", guild_skill_db);
for(i=0;i<MAX_GUILDSKILL;i++){
if (g->skill[i].id>0){
- if (first == 0)
- StringBuf_Printf(&sbuf , ", ");
- else
- first = 0;
- StringBuf_Printf(&sbuf, "('%d','%d','%d')",
- g->guild_id,g->skill[i].id,g->skill[i].lv);
+ sprintf(tmp_sql,"INSERT INTO `%s` (`guild_id`,`id`,`lv`) VALUES ('%d','%d','%d')",
+ guild_skill_db, g->guild_id,g->skill[i].id,g->skill[i].lv);
+ //printf("%s\n",tmp_sql);
+ if(mysql_query(&mysql_handle, tmp_sql) ) {
+ printf("DB server Error (insert `guild_skill`)- %s\n", mysql_error(&mysql_handle) );
+ }
}
}
- StringBuf_Printf(&sbuf ,";\n");
}
- if(mysql_query(&mysql_handle, StringBuf_Value(&sbuf)))
- printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
-
- StringBuf_Destroy(&sbuf);
-
printf("Save guild done\n");
return 0;
}
@@ -272,15 +323,15 @@ struct guild * inter_guild_fromsql(int guild_id)
char *pstr;
struct guild *g;
- if (guild_id==0) return 0;
+ if (guild_id<=0) return 0;
- g = numdb_search(guild_db_,guild_id);
+ g = (struct guild*)numdb_search(guild_db_,guild_id);
if (g != NULL)
return g;
-
- g = (struct guild *) malloc(sizeof(struct guild));
+
+ g = (struct guild*)aMalloc(sizeof(struct guild));
memset(g,0,sizeof(struct guild));
-
+
// printf("Retrieve guild information from sql ......\n");
// printf("- Read guild %d from sql \n",guild_id);
@@ -289,25 +340,28 @@ struct guild * inter_guild_fromsql(int guild_id)
//printf(" %s\n",tmp_sql);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (select `guild`)- %s\n", mysql_error(&mysql_handle) );
- free(g);
+ aFree(g);
return 0;
}
-
+
sql_res = mysql_store_result(&mysql_handle) ;
if (sql_res!=NULL && mysql_num_rows(sql_res)>0) {
sql_row = mysql_fetch_row(sql_res);
if (sql_row==NULL) {
mysql_free_result(sql_res);
- free(g);
+ aFree(g);
return 0;
}
-
+
g->guild_id=atoi(sql_row[0]);
strncpy(g->name,sql_row[1],24);
strncpy(g->master,sql_row[2],24);
g->guild_lv=atoi(sql_row[3]);
g->connect_member=atoi(sql_row[4]);
- g->max_member=atoi(sql_row[5]);
+ if (atoi(sql_row[5]) > MAX_GUILD) // Fix reduction of MAX_GUILD [PoW]
+ g->max_member = MAX_GUILD;
+ else
+ g->max_member = atoi(sql_row[5]);
g->average_lv=atoi(sql_row[6]);
g->exp=atoi(sql_row[7]);
g->next_exp=atoi(sql_row[8]);
@@ -327,7 +381,7 @@ struct guild * inter_guild_fromsql(int guild_id)
if(c2>='a' && c2<='f')x2=c2-'a'+10;
if(c2>='A' && c2<='F')x2=c2-'A'+10;
g->emblem_data[i]=(x1<<4)|x2;
- }
+ }
}
mysql_free_result(sql_res);
@@ -337,7 +391,7 @@ struct guild * inter_guild_fromsql(int guild_id)
//printf(" %s\n",tmp_sql);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (select `guild_member`)- %s\n", mysql_error(&mysql_handle) );
- free(g);
+ aFree(g);
return 0;
}
sql_res = mysql_store_result(&mysql_handle) ;
@@ -350,43 +404,47 @@ struct guild * inter_guild_fromsql(int guild_id)
m->hair=atoi(sql_row[3]);
m->hair_color=atoi(sql_row[4]);
m->gender=atoi(sql_row[5]);
- m->class=atoi(sql_row[6]);
+ m->class_=atoi(sql_row[6]);
m->lv=atoi(sql_row[7]);
m->exp=atoi(sql_row[8]);
m->exp_payper=atoi(sql_row[9]);
- m->online=atoi(sql_row[10]);
- m->position=atoi(sql_row[11]);
+ m->online=atoi(sql_row[10]);
+ if (atoi(sql_row[11]) >= MAX_GUILDPOSITION) // Fix reduction of MAX_GUILDPOSITION [PoW]
+ m->position = MAX_GUILDPOSITION - 1;
+ else
+ m->position = atoi(sql_row[11]);
+
strncpy(m->name,sql_row[14],24);
}
}
mysql_free_result(sql_res);
-
+
//printf("- Read guild_position %d from sql \n",guild_id);
sprintf(tmp_sql,"SELECT `guild_id`,`position`,`name`,`mode`,`exp_mode` FROM `%s` WHERE `guild_id`='%d'",guild_position_db, guild_id);
//printf(" %s\n",tmp_sql);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (select `guild_position`)- %s\n", mysql_error(&mysql_handle) );
- free(g);
+ aFree(g);
return 0;
}
sql_res = mysql_store_result(&mysql_handle) ;
if (sql_res!=NULL && mysql_num_rows(sql_res)>0) {
int i;
for(i=0;((sql_row = mysql_fetch_row(sql_res))&&i<MAX_GUILDPOSITION);i++){
- int position = atoi(sql_row[1]);
+ int position = atoi(sql_row[1]);
struct guild_position *p = &g->position[position];
- strncpy(p->name,sql_row[2],24);
+ strncpy(p->name,sql_row[2],24);
p->mode=atoi(sql_row[3]);
- p->exp_mode=atoi(sql_row[4]);
+ p->exp_mode=atoi(sql_row[4]);
}
}
- mysql_free_result(sql_res);
+ mysql_free_result(sql_res);
//printf("- Read guild_alliance %d from sql \n",guild_id);
sprintf(tmp_sql,"SELECT `guild_id`,`opposition`,`alliance_id`,`name` FROM `%s` WHERE `guild_id`='%d'",guild_alliance_db, guild_id);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (select `guild_alliance`)- %s\n", mysql_error(&mysql_handle) );
- free(g);
+ aFree(g);
return 0;
}
sql_res = mysql_store_result(&mysql_handle) ;
@@ -400,12 +458,12 @@ struct guild * inter_guild_fromsql(int guild_id)
}
}
mysql_free_result(sql_res);
-
+
//printf("- Read guild_expulsion %d from sql \n",guild_id);
sprintf(tmp_sql,"SELECT `guild_id`,`name`,`mes`,`acc`,`account_id`,`rsv1`,`rsv2`,`rsv3` FROM `%s` WHERE `guild_id`='%d'",guild_expulsion_db, guild_id);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (select `guild_expulsion`)- %s\n", mysql_error(&mysql_handle) );
- free(g);
+ aFree(g);
return 0;
}
sql_res = mysql_store_result(&mysql_handle) ;
@@ -421,16 +479,16 @@ struct guild * inter_guild_fromsql(int guild_id)
e->rsv1=atoi(sql_row[5]);
e->rsv2=atoi(sql_row[6]);
e->rsv3=atoi(sql_row[7]);
-
+
}
}
mysql_free_result(sql_res);
-
+
//printf("- Read guild_skill %d from sql \n",guild_id);
sprintf(tmp_sql,"SELECT `guild_id`,`id`,`lv` FROM `%s` WHERE `guild_id`='%d' ORDER BY `id`",guild_skill_db, guild_id);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (select `guild_skill`)- %s\n", mysql_error(&mysql_handle) );
- free(g);
+ aFree(g);
return 0;
}
sql_res = mysql_store_result(&mysql_handle) ;
@@ -442,7 +500,7 @@ struct guild * inter_guild_fromsql(int guild_id)
}
}
mysql_free_result(sql_res);
-
+
// printf("Successfully retrieve guild information from sql!\n");
numdb_insert(guild_db_, guild_id,g);
@@ -450,21 +508,40 @@ struct guild * inter_guild_fromsql(int guild_id)
return g;
}
-// Save guild_castle to sql
+#if 1
+static int _set_guild_castle(void *key, void *data, va_list ap) {
+ int castle_id = va_arg(ap, int);
+ int guild_id = va_arg(ap, int);
+ struct guild * g = (struct guild *) data;
+
+ if (g->castle_id == castle_id)
+ g->castle_id = -1;
+ if (g->guild_id == guild_id)
+ g->castle_id = castle_id;
+ return 0;
+}
+#endif
+
int inter_guildcastle_tosql(struct guild_castle *gc)
{
- // `guild_castle` (`castle_id`, `guild_id`, `economy`, `defense`, `triggerE`, `triggerD`, `nextTime`, `payTime`, `createTime`, `visibleC`, `visibleG0`, `visibleG1`, `visibleG2`, `visibleG3`, `visibleG4`, `visibleG5`, `visibleG6`, `visibleG7`)
-
- if (gc==NULL) return 0;
- //printf("Save to guild_castle\n");
- sprintf(tmp_sql,"DELETE FROM `%s` WHERE `castle_id`='%d'",guild_castle_db, gc->castle_id);
- //printf(" %s\n",tmp_sql);
- if(mysql_query(&mysql_handle, tmp_sql) ) {
- printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
+ struct guild_castle *gcopy;
+ if(gc == NULL || gc->castle_id < 0 ){ //gc->castle_id can be == 0 (for the 1st castle it's == 0) [Lupus]
return 0;
}
-
- sprintf(tmp_sql,"INSERT INTO `%s` "
+ //printf("[Guild Castle %02i]: Save...\n",gc->castle_id);
+ gcopy = (struct guild_castle *) numdb_search(castle_db_,gc->castle_id);
+ if (gcopy == NULL) {
+ gcopy = (struct guild_castle *) aMalloc(sizeof(struct guild_castle));
+ numdb_insert(castle_db_, gc->castle_id, gcopy);
+ } else {
+ //if the castle data hasn't been changed, then we don't write it into SQL
+ if ((gc->guild_id == gcopy->guild_id ) && ( gc->economy == gcopy->economy ) && ( gc->defense == gcopy->defense ) && ( gc->triggerE == gcopy->triggerE ) && ( gc->triggerD == gcopy->triggerD ) && ( gc->nextTime == gcopy->nextTime ) && ( gc->payTime == gcopy->payTime ) && ( gc->createTime == gcopy->createTime ) && ( gc->visibleC == gcopy->visibleC ) && ( gc->visibleG0 == gcopy->visibleG0 ) && ( gc->visibleG1 == gcopy->visibleG1 ) && ( gc->visibleG2 == gcopy->visibleG2 ) && ( gc->visibleG3 == gcopy->visibleG3 ) && ( gc->visibleG4 == gcopy->visibleG4 ) && ( gc->visibleG5 == gcopy->visibleG5 ) && ( gc->visibleG6 == gcopy->visibleG6 ) && ( gc->visibleG7 == gcopy->visibleG7 ) && ( gc->Ghp0 == gcopy->Ghp0 ) && ( gc->Ghp1 == gcopy->Ghp1 ) && ( gc->Ghp2 == gcopy->Ghp2 ) && ( gc->Ghp3 == gcopy->Ghp3 ) && ( gc->Ghp4 == gcopy->Ghp4 ) && ( gc->Ghp5 == gcopy->Ghp5 ) && ( gc->Ghp6 == gcopy->Ghp6 ) && ( gc->Ghp7 == gcopy->Ghp7 ))
+ return 0;
+ }
+ //printf("[Guild Castle %02i]: Save... ->SQL\n",gc->castle_id);
+ memcpy(gcopy, gc, sizeof(struct guild_castle));
+
+ sprintf(tmp_sql,"REPLACE INTO `%s` "
"(`castle_id`, `guild_id`, `economy`, `defense`, `triggerE`, `triggerD`, `nextTime`, `payTime`, `createTime`,"
"`visibleC`, `visibleG0`, `visibleG1`, `visibleG2`, `visibleG3`, `visibleG4`, `visibleG5`, `visibleG6`, `visibleG7`,"
"`Ghp0`, `Ghp1`, `Ghp2`, `Ghp3`, `Ghp4`, `Ghp5`, `Ghp6`, `Ghp7`)"
@@ -472,35 +549,35 @@ int inter_guildcastle_tosql(struct guild_castle *gc)
guild_castle_db, gc->castle_id, gc->guild_id, gc->economy, gc->defense, gc->triggerE, gc->triggerD, gc->nextTime, gc->payTime,
gc->createTime, gc->visibleC, gc->visibleG0, gc->visibleG1, gc->visibleG2, gc->visibleG3, gc->visibleG4, gc->visibleG5,
gc->visibleG6, gc->visibleG7, gc->Ghp0, gc->Ghp1, gc->Ghp2, gc->Ghp3, gc->Ghp4, gc->Ghp5, gc->Ghp6, gc->Ghp7);
- //printf(" %s\n",tmp_sql);
- if(mysql_query(&mysql_handle, tmp_sql) ) {
- printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
- return 0;
- }
- sprintf(tmp_sql,"UPDATE `%s` SET `castle_id`='-1' WHERE `castle_id`='%d'",guild_db, gc->castle_id);
- //printf(" %s\n",tmp_sql);
- if(mysql_query(&mysql_handle, tmp_sql) ) {
- printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
- return 0;
- }
-
- sprintf(tmp_sql,"UPDATE `%s` SET `castle_id`='%d' WHERE `guild_id`='%d'",guild_db, gc->castle_id,gc->guild_id);
//printf(" %s\n",tmp_sql);
+
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
return 0;
}
+
+ db_foreach(guild_db_, _set_guild_castle, gc->castle_id,gc->guild_id);
return 0;
}
+
// Read guild_castle from sql
int inter_guildcastle_fromsql(int castle_id,struct guild_castle *gc)
{
-
+ struct guild_castle *gcopy;
if (gc==NULL) return 0;
//printf("Read from guild_castle\n");
- memset(gc,0,sizeof(struct guild_castle));
+
+ gcopy = (struct guild_castle*)numdb_search(castle_db_, castle_id);
+ if (gcopy == NULL) {
+ gcopy = (struct guild_castle*)aMalloc(sizeof(struct guild_castle));
+ numdb_insert(castle_db_, gc->castle_id, gcopy);
+ } else {
+ memcpy(gc, gcopy, sizeof(struct guild_castle));
+ return 0;
+ }
+
gc->castle_id=castle_id;
if (castle_id==-1) return 0;
sprintf(tmp_sql,"SELECT `castle_id`, `guild_id`, `economy`, `defense`, `triggerE`, `triggerD`, `nextTime`, `payTime`, `createTime`, "
@@ -518,7 +595,7 @@ int inter_guildcastle_fromsql(int castle_id,struct guild_castle *gc)
mysql_free_result(sql_res);
return 0;
}
-
+
gc->guild_id = atoi (sql_row[1]);
gc->economy = atoi (sql_row[2]);
gc->defense = atoi (sql_row[3]);
@@ -544,11 +621,14 @@ int inter_guildcastle_fromsql(int castle_id,struct guild_castle *gc)
gc->Ghp5 = atoi (sql_row[23]);
gc->Ghp6 = atoi (sql_row[24]);
gc->Ghp7 = atoi (sql_row[25]);
-
+
//printf("Read Castle %d of guild %d from sql \n",castle_id,gc->guild_id);
}
mysql_free_result(sql_res) ; //resource free
+
+ memcpy(gcopy, gc, sizeof(struct guild_castle));
+
return 0;
}
@@ -559,7 +639,7 @@ int inter_guild_readdb()
FILE *fp;
char line[1024];
for (i=0;i<100;i++) guild_exp[i]=0;
-
+
fp=fopen("db/exp_guild.txt","r");
if(fp==NULL){
printf("can't read db/exp_guild.txt\n");
@@ -585,17 +665,14 @@ int inter_guild_sql_init()
guild_db_=numdb_init();
castle_db_=numdb_init();
- guild_expcache_db_=numdb_init();
- guild_infoevent_db_=numdb_init();
- guild_castleinfoevent_db_=numdb_init();
-
+
printf("interserver guild memory initialize.... (%d byte)\n",sizeof(struct guild));
- guild_pt = calloc(sizeof(struct guild), 1);
- guild_pt2= calloc(sizeof(struct guild), 1);
- guildcastle_pt=calloc(sizeof(struct guild_castle), 1);
-
+ guild_pt = (struct guild*)aCalloc(sizeof(struct guild), 1);
+ guild_pt2= (struct guild*)aCalloc(sizeof(struct guild), 1);
+ guildcastle_pt = (struct guild_castle*)aCalloc(sizeof(struct guild_castle), 1);
+
inter_guild_readdb(); // Read exp
-
+
sprintf (tmp_sql , "SELECT count(*) FROM `%s`",guild_db);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
@@ -614,18 +691,41 @@ int inter_guild_sql_init()
printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
exit(0);
}
-
+
sql_res = mysql_store_result(&mysql_handle) ;
sql_row = mysql_fetch_row(sql_res);
guild_newid = atoi(sql_row[0])+1;
mysql_free_result(sql_res);
}
-
+
printf("set guild_newid: %d.......\n",guild_newid);
return 0;
}
+int guild_db_final (void *k, void *data, va_list ap)
+{
+ struct guild *g = (struct guild *) data;
+ if (g) aFree(g);
+ return 0;
+}
+int castle_db_final (void *k, void *data, va_list ap)
+{
+ struct guild_castle *gc = (struct guild_castle *) data;
+ if (gc) aFree(gc);
+ return 0;
+}
+void inter_guild_sql_final()
+{
+ if (guild_pt) aFree(guild_pt);
+ if (guild_pt2) aFree(guild_pt2);
+ if (guildcastle_pt) aFree(guildcastle_pt);
+
+ numdb_final(guild_db_, guild_db_final);
+ numdb_final(castle_db_, castle_db_final);
+
+ return;
+}
// Get guild by its name
struct guild* search_guildname(char *str)
@@ -655,7 +755,7 @@ int guild_check_empty(struct guild *g)
return 0;
}
}
-
+
// ’N‚à‚¢‚È‚¢‚̂ʼnðŽU
mapif_guild_broken(g->guild_id,0);
inter_guild_storage_delete(g->guild_id);
@@ -707,7 +807,7 @@ int guild_calcinfo(struct guild *g)
nextexp = guild_nextexp(g->guild_lv);
}
}
-
+
// ƒMƒ‹ƒh‚ÌŽŸ‚ÌŒoŒ±’l
g->next_exp = guild_nextexp(g->guild_lv);
@@ -721,13 +821,13 @@ int guild_calcinfo(struct guild *g)
if(g->member[i].account_id>0){
g->average_lv+=g->member[i].lv;
c++;
-
+
if(g->member[i].online>0)
g->connect_member++;
}
}
if(c) g->average_lv/=c;
-
+
// ‘Sƒf[ƒ^‚ð‘—‚é•K—v‚ª‚ ‚è‚»‚¤
if( g->max_member!=before.max_member ||
g->guild_lv!=before.guild_lv ||
@@ -735,7 +835,7 @@ int guild_calcinfo(struct guild *g)
mapif_guild_info(-1,g);
return 1;
}
-
+
return 0;
}
@@ -818,9 +918,9 @@ int mapif_guild_memberinfoshort(struct guild *g,int idx)
WBUFL(buf, 2)=g->guild_id;
WBUFL(buf, 6)=g->member[idx].account_id;
WBUFL(buf,10)=g->member[idx].char_id;
- WBUFB(buf,14)=g->member[idx].online;
+ WBUFB(buf,14)=(unsigned char)g->member[idx].online;
WBUFW(buf,15)=g->member[idx].lv;
- WBUFW(buf,17)=g->member[idx].class;
+ WBUFW(buf,17)=g->member[idx].class_;
mapif_sendall(buf,19);
return 0;
}
@@ -838,7 +938,7 @@ int mapif_guild_broken(int guild_id,int flag)
}
// ƒMƒ‹ƒh“à”­Œ¾
-int mapif_guild_message(int guild_id,int account_id,char *mes,int len)
+int mapif_guild_message(int guild_id,int account_id,char *mes,int len, int sfd)
{
unsigned char buf[512];
WBUFW(buf,0)=0x3837;
@@ -846,7 +946,7 @@ int mapif_guild_message(int guild_id,int account_id,char *mes,int len)
WBUFL(buf,4)=guild_id;
WBUFL(buf,8)=account_id;
memcpy(WBUFP(buf,12),mes,len);
- mapif_sendall(buf,len+12);
+ mapif_sendallwos(sfd, buf,len+12);
return 0;
}
@@ -966,6 +1066,7 @@ int mapif_guild_castle_datasave(int castle_id,int index,int value) // <Agit
int mapif_guild_castle_alldataload(int fd) {
struct guild_castle* gc = guildcastle_pt;
+ struct guild_castle *gcopy;
int i, len = 4;
WFIFOW(fd,0) = 0x3842;
@@ -1004,6 +1105,14 @@ int mapif_guild_castle_alldataload(int fd) {
gc->Ghp6 = atoi(sql_row[24]);
gc->Ghp7 = atoi(sql_row[25]);
memcpy(WFIFOP(fd,len), gc, sizeof(struct guild_castle));
+
+ gcopy = (struct guild_castle*)numdb_search(castle_db_,gc->castle_id);
+ if (gcopy == NULL) {
+ gcopy = (struct guild_castle *) aMalloc(sizeof(struct guild_castle));
+ numdb_insert(castle_db_, gc->castle_id, gcopy);
+ }
+ memcpy(gcopy, gc, sizeof(struct guild_castle));
+
len += sizeof(struct guild_castle);
}
}
@@ -1024,7 +1133,7 @@ int mapif_parse_CreateGuild(int fd,int account_id,char *name,struct guild_member
{
struct guild *g;
int i;
-
+
printf("CreateGuild\n");
g=search_guildname(name);
if(g!=NULL&&g->guild_id>0){
@@ -1038,38 +1147,38 @@ int mapif_parse_CreateGuild(int fd,int account_id,char *name,struct guild_member
memcpy(g->name,name,24);
memcpy(g->master,master->name,24);
memcpy(&g->member[0],master,sizeof(struct guild_member));
-
+
g->position[0].mode=0x11;
- strcpy(g->position[ 0].name,"GuildMaster");
+ strcpy(g->position[0].name,"GuildMaster");
strcpy(g->position[MAX_GUILDPOSITION-1].name,"Newbie");
for(i=1;i<MAX_GUILDPOSITION-1;i++)
sprintf(g->position[i].name,"Position %d",i+1);
-
+
// Initialize guild property
g->max_member=16;
g->average_lv=master->lv;
g->castle_id=-1;
for(i=0;i<MAX_GUILDSKILL;i++)
g->skill[i].id=i + GD_SKILLBASE;
-
+
// Save to sql
printf("Create initialize OK!\n");
i=inter_guild_tosql(g,255);
-
+
if (i<0) {
mapif_guild_created(fd,account_id,NULL);
return 0;
}
-
+
// Report to client
mapif_guild_created(fd,account_id,g);
mapif_guild_info(fd,g);
-
+
if(log_inter)
inter_log("guild %s (id=%d) created by master %s (id=%d)" RETCODE,
name, g->guild_id, master->name, master->account_id );
-
-
+
+
return 0;
}
// Return guild info to client
@@ -1089,15 +1198,15 @@ int mapif_parse_GuildAddMember(int fd,int guild_id,struct guild_member *m)
{
struct guild *g = inter_guild_fromsql(guild_id);
int i;
-
+
if(g==NULL||g->guild_id<=0){
mapif_guild_memberadded(fd,guild_id,m->account_id,m->char_id,1);
return 0;
}
-
+
for(i=0;i<g->max_member;i++){
if(g->member[i].account_id==0){
-
+
memcpy(&g->member[i],m,sizeof(struct guild_member));
mapif_guild_memberadded(fd,guild_id,m->account_id,m->char_id,0);
guild_calcinfo(g);
@@ -1114,7 +1223,7 @@ int mapif_parse_GuildAddMember(int fd,int guild_id,struct guild_member *m)
int mapif_parse_GuildLeave(int fd,int guild_id,int account_id,int char_id,int flag,const char *mes)
{
struct guild *g= inter_guild_fromsql(guild_id);
-
+
if(g!=NULL&&g->guild_id>0){
int i;
for(i=0;i<g->max_member;i++){
@@ -1122,7 +1231,7 @@ int mapif_parse_GuildLeave(int fd,int guild_id,int account_id,int char_id,int fl
g->member[i].char_id==char_id){
printf("%d %d\n",i, (int)(&g->member[i]));
printf("%d %s\n",i, g->member[i].name);
-
+
if(flag){ // ’Ç•ú‚ÌꇒǕúƒŠƒXƒg‚É“ü‚ê‚é
int j;
for(j=0;j<MAX_GUILDEXPLUSION;j++){
@@ -1139,17 +1248,17 @@ int mapif_parse_GuildLeave(int fd,int guild_id,int account_id,int char_id,int fl
memcpy(g->explusion[j].name,g->member[i].name,24);
memcpy(g->explusion[j].mes,mes,40);
}
-
+
mapif_guild_leaved(guild_id,account_id,char_id,flag,g->member[i].name,mes);
printf("%d %d\n",i, (int)(&g->member[i]));
printf("%d %s\n",i, (&g->member[i])->name);
memset(&g->member[i],0,sizeof(struct guild_member));
-
+
if( guild_check_empty(g)==0 )
mapif_guild_info(-1,g);// ‚Ü‚¾l‚ª‚¢‚é‚̂Ńf[ƒ^‘—M
/*
else
- inter_guild_save(); // ‰ðŽU‚µ‚½‚̂ňꉞƒZ[ƒu
+ inter_guild_save(); // ‰ðŽU‚µ‚½‚̂ňê‰cZ[ƒu
return 0;*/
}
}
@@ -1162,31 +1271,33 @@ int mapif_parse_GuildLeave(int fd,int guild_id,int account_id,int char_id,int fl
}
/* mapif_guild_leaved(guild_id,account_id,char_id,flag,g->member[i].name,mes); */
}
-
+
return 0;
}
-
// Change member info
int mapif_parse_GuildChangeMemberInfoShort(int fd,int guild_id,
- int account_id,int char_id,int online,int lv,int class)
+ int account_id,int char_id,int online,int lv,int class_)
{
// Could speed up by manipulating only guild_member
struct guild * g= inter_guild_fromsql(guild_id);
- int i,alv,c;
+ int i,alv,c, idx;
if(g==NULL||g->guild_id<=0)
return 0;
-
+
g->connect_member=0;
-
+
+ idx = -1;
+
for(i=0,alv=0,c=0;i<g->max_member;i++){
if( g->member[i].account_id==account_id &&
g->member[i].char_id==char_id){
-
+
g->member[i].online=online;
g->member[i].lv=lv;
- g->member[i].class=class;
+ g->member[i].class_=class_;
mapif_guild_memberinfoshort(g,i);
+ idx = i;
}
if( g->member[i].account_id>0 ){
alv+=g->member[i].lv;
@@ -1195,11 +1306,19 @@ int mapif_parse_GuildChangeMemberInfoShort(int fd,int guild_id,
if( g->member[i].online )
g->connect_member++;
}
- // •½‹ÏƒŒƒxƒ‹
- g->average_lv=alv/c;
-
- inter_guild_tosql(g,3); // Change guild & guild_member
-
+
+ if (c)
+ // •½‹ÏƒŒƒxƒ‹
+ g->average_lv=alv/c;
+
+ sprintf(tmp_sql, "UPDATE `%s` SET `connect_member`=%d,`average_lv`=%d WHERE `guild_id`='%d'", guild_db, g->connect_member, g->average_lv, g->guild_id);
+ if(mysql_query(&mysql_handle, tmp_sql) )
+ printf("DB server Error: %s - %s\n", tmp_sql, mysql_error(&mysql_handle) );
+
+ sprintf(tmp_sql, "UPDATE `%s` SET `online`=%d,`lv`=%d,`class`=%d WHERE `char_id`=%d", guild_member_db, g->member[idx].online, g->member[idx].lv, g->member[idx].class_, g->member[idx].char_id);
+ if(mysql_query(&mysql_handle, tmp_sql) )
+ printf("DB server Error: %s - %s\n", tmp_sql, mysql_error(&mysql_handle) );
+
return 0;
}
@@ -1209,7 +1328,7 @@ int mapif_parse_BreakGuild(int fd,int guild_id)
struct guild *g= inter_guild_fromsql(guild_id);
if(g==NULL)
return 0;
-
+
// Delete guild from sql
//printf("- Delete guild %d from guild\n",guild_id);
sprintf(tmp_sql, "DELETE FROM `%s` WHERE `guild_id`='%d'",guild_db, guild_id);
@@ -1241,32 +1360,34 @@ int mapif_parse_BreakGuild(int fd,int guild_id)
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (delete `guild_position`)- %s\n", mysql_error(&mysql_handle) );
}
-
+
//printf("- Delete guild %d from guild_castle\n",guild_id);
sprintf(tmp_sql, "DELETE FROM `%s` WHERE `guild_id`='%d'",guild_castle_db, guild_id);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (delete `guild_position`)- %s\n", mysql_error(&mysql_handle) );
}
-
+
+ db_foreach(castle_db_, _erase_guild, guild_id);
+
//printf("- Update guild %d of char\n",guild_id);
sprintf(tmp_sql, "UPDATE `%s` SET `guild_id`='0' WHERE `guild_id`='%d'",char_db, guild_id);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (delete `guild_position`)- %s\n", mysql_error(&mysql_handle) );
}
-
+
inter_guild_storage_delete(guild_id);
mapif_guild_broken(guild_id,0);
-
+
if(log_inter)
inter_log("guild %s (id=%d) broken" RETCODE,g->name,guild_id);
-
+
return 0;
}
// ƒMƒ‹ƒhƒƒbƒZ[ƒW‘—M
int mapif_parse_GuildMessage(int fd,int guild_id,int account_id,char *mes,int len)
{
- return mapif_guild_message(guild_id,account_id,mes,len);
+ return mapif_guild_message(guild_id,account_id,mes,len, fd);
}
// ƒMƒ‹ƒhŠî–{ƒf[ƒ^•ÏX—v‹
int mapif_parse_GuildBasicInfoChange(int fd,int guild_id,
@@ -1307,7 +1428,7 @@ int mapif_parse_GuildMemberInfoChange(int fd,int guild_id,int account_id,int cha
struct guild * g = inter_guild_fromsql(guild_id);
//printf("GuildMemberInfoChange %s \n",(type==GMI_EXP)?"GMI_EXP":"OTHER");
-
+
if(g==NULL){
return 0;
}
@@ -1322,21 +1443,34 @@ int mapif_parse_GuildMemberInfoChange(int fd,int guild_id,int account_id,int cha
}
switch(type){
case GMI_POSITION: // –ðE
- g->member[i].position=*((int *)data);
- break;
- case GMI_EXP: { // EXP
- int exp,oldexp=g->member[i].exp;
- exp=g->member[i].exp=*((unsigned int *)data);
- g->exp+=(exp-oldexp);
- guild_calcinfo(g); // LvƒAƒbƒv”»’f
- mapif_guild_basicinfochanged(guild_id,GBI_EXP,&g->exp,4);
- }break;
+ {
+ g->member[i].position=*((int *)data);
+ mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
+ inter_guild_tosql(g,3); // Change guild & guild_member
+ break;
+ }
+ case GMI_EXP:
+ { // EXP
+ int exp,oldexp=g->member[i].exp;
+ exp=g->member[i].exp=*((unsigned int *)data);
+ g->exp+=(exp-oldexp);
+ guild_calcinfo(g); // LvƒAƒbƒv”»’f
+ mapif_guild_basicinfochanged(guild_id,GBI_EXP,&g->exp,4);
+ mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
+
+ sprintf(tmp_sql, "UPDATE `%s` SET `guild_lv`=%d,`connect_member`=%d,`max_member`=%d,`average_lv`=%d,`exp`=%d,`next_exp`=%d,`skill_point`=%d WHERE `guild_id`='%d'", guild_db, g->guild_lv, g->connect_member, g->max_member, g->average_lv, g->exp, g->next_exp, g->skill_point, g->guild_id);
+ if(mysql_query(&mysql_handle, tmp_sql) )
+ printf("DB server Error: %s - %s\n", tmp_sql, mysql_error(&mysql_handle) );
+
+ sprintf(tmp_sql, "UPDATE `%s` SET `exp`=%d WHERE `char_id`=%d", guild_member_db, g->member[i].exp, g->member[i].char_id);
+ if(mysql_query(&mysql_handle, tmp_sql) )
+ printf("DB server Error: %s - %s\n", tmp_sql, mysql_error(&mysql_handle) );
+ break;
+ }
default:
- printf("int_guild: GuildMemberInfoChange: Unknown type %d\n",type);
- break;
+ printf("int_guild: GuildMemberInfoChange: Unknown type %d\n",type);
+ break;
}
- mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
- inter_guild_tosql(g,3); // Change guild & guild_member
return 0;
}
@@ -1362,10 +1496,11 @@ int mapif_parse_GuildSkillUp(int fd,int guild_id,int skill_num,int account_id)
struct guild *g = inter_guild_fromsql(guild_id);
int idx = skill_num - GD_SKILLBASE;
+
if(g == NULL || idx < 0 || idx >= MAX_GUILDSKILL)
return 0;
//printf("GuildSkillUp\n");
-
+
if( g->skill_point>0 && g->skill[idx].id>0 &&
g->skill[idx].lv<10 ){
g->skill[idx].lv++;
@@ -1388,10 +1523,10 @@ int mapif_parse_GuildAlliance(int fd,int guild_id1,int guild_id2,
int j,i;
g[0]= inter_guild_fromsql(guild_id1);
g[1]= inter_guild_fromsql(guild_id2);
-
+
if(g[0]==NULL || g[1]==NULL || g[0]->guild_id ==0 || g[1]->guild_id==0)
return 0;
-
+
if(!(flag&0x8)){
for(i=0;i<2-(flag&1);i++){
for(j=0;j<MAX_GUILDALLIANCE;j++)
@@ -1422,7 +1557,7 @@ int mapif_parse_GuildAlliance(int fd,int guild_id1,int guild_id2,
int mapif_parse_GuildNotice(int fd,int guild_id,const char *mes1,const char *mes2)
{
struct guild *g= inter_guild_fromsql(guild_id);
-
+
if(g==NULL||g->guild_id<=0)
return 0;
memcpy(g->mes1,mes1,60);
@@ -1434,7 +1569,7 @@ int mapif_parse_GuildNotice(int fd,int guild_id,const char *mes1,const char *mes
int mapif_parse_GuildEmblem(int fd,int len,int guild_id,int dummy,const char *data)
{
struct guild * g= inter_guild_fromsql(guild_id);
-
+
if(g==NULL||g->guild_id<=0)
return 0;
memcpy(g->emblem_data,data,len);
@@ -1497,7 +1632,7 @@ int mapif_parse_GuildCastleDataSave(int fd,int castle_id,int index,int value)
struct guild *g=inter_guild_fromsql(gid);
if(log_inter)
inter_log("guild %s (id=%d) %s castle id=%d" RETCODE,
- (g)?g->name:"??" ,gid, (value)?"occupy":"abandon", index);
+ (g)?g->name:"??" ,gid, (value)?"occupy":"abandon", castle_id);
}
gc->guild_id = value;
break;
@@ -1548,21 +1683,21 @@ int mapif_parse_GuildCheck(int fd,int guild_id,int account_id,int char_id)
int inter_guild_parse_frommap(int fd)
{
switch(RFIFOW(fd,0)){
- case 0x3030: mapif_parse_CreateGuild(fd,RFIFOL(fd,4),RFIFOP(fd,8),(struct guild_member *)RFIFOP(fd,32)); break;
+ case 0x3030: mapif_parse_CreateGuild(fd,RFIFOL(fd,4),(char*)RFIFOP(fd,8),(struct guild_member *)RFIFOP(fd,32)); break;
case 0x3031: mapif_parse_GuildInfo(fd,RFIFOL(fd,2)); break;
case 0x3032: mapif_parse_GuildAddMember(fd,RFIFOL(fd,4),(struct guild_member *)RFIFOP(fd,8)); break;
- case 0x3034: mapif_parse_GuildLeave(fd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14),RFIFOP(fd,15)); break;
+ case 0x3034: mapif_parse_GuildLeave(fd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14),(const char*)RFIFOP(fd,15)); break;
case 0x3035: mapif_parse_GuildChangeMemberInfoShort(fd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14),RFIFOW(fd,15),RFIFOW(fd,17)); break;
case 0x3036: mapif_parse_BreakGuild(fd,RFIFOL(fd,2)); break;
- case 0x3037: mapif_parse_GuildMessage(fd,RFIFOL(fd,4),RFIFOL(fd,8),RFIFOP(fd,12),RFIFOW(fd,2)-12); break;
+ case 0x3037: mapif_parse_GuildMessage(fd,RFIFOL(fd,4),RFIFOL(fd,8),(char*)RFIFOP(fd,12),RFIFOW(fd,2)-12); break;
case 0x3038: mapif_parse_GuildCheck(fd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10)); break;
- case 0x3039: mapif_parse_GuildBasicInfoChange(fd,RFIFOL(fd,4),RFIFOW(fd,8),RFIFOP(fd,10),RFIFOW(fd,2)-10); break;
- case 0x303A: mapif_parse_GuildMemberInfoChange(fd,RFIFOL(fd,4),RFIFOL(fd,8),RFIFOL(fd,12),RFIFOW(fd,16),RFIFOP(fd,18),RFIFOW(fd,2)-18); break;
+ case 0x3039: mapif_parse_GuildBasicInfoChange(fd,RFIFOL(fd,4),RFIFOW(fd,8),(const char*)RFIFOP(fd,10),RFIFOW(fd,2)-10); break;
+ case 0x303A: mapif_parse_GuildMemberInfoChange(fd,RFIFOL(fd,4),RFIFOL(fd,8),RFIFOL(fd,12),RFIFOW(fd,16),(const char*)RFIFOP(fd,18),RFIFOW(fd,2)-18); break;
case 0x303B: mapif_parse_GuildPosition(fd,RFIFOL(fd,4),RFIFOL(fd,8),(struct guild_position *)RFIFOP(fd,12)); break;
case 0x303C: mapif_parse_GuildSkillUp(fd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10)); break;
case 0x303D: mapif_parse_GuildAlliance(fd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOL(fd,14),RFIFOB(fd,18)); break;
- case 0x303E: mapif_parse_GuildNotice(fd,RFIFOL(fd,2),RFIFOP(fd,6),RFIFOP(fd,66)); break;
- case 0x303F: mapif_parse_GuildEmblem(fd,RFIFOW(fd,2)-12,RFIFOL(fd,4),RFIFOL(fd,8),RFIFOP(fd,12)); break;
+ case 0x303E: mapif_parse_GuildNotice(fd,RFIFOL(fd,2),(const char*)RFIFOP(fd,6),(const char*)RFIFOP(fd,66)); break;
+ case 0x303F: mapif_parse_GuildEmblem(fd,RFIFOW(fd,2)-12,RFIFOL(fd,4),RFIFOL(fd,8),(const char*)RFIFOP(fd,12)); break;
case 0x3040: mapif_parse_GuildCastleDataLoad(fd,RFIFOW(fd,2),RFIFOB(fd,4)); break;
case 0x3041: mapif_parse_GuildCastleDataSave(fd,RFIFOW(fd,2),RFIFOB(fd,4),RFIFOL(fd,5)); break;
diff --git a/src/char_sql/int_guild.h b/src/char_sql/int_guild.h
index 8f4203d7c..8257cf8f6 100644
--- a/src/char_sql/int_guild.h
+++ b/src/char_sql/int_guild.h
@@ -3,6 +3,7 @@
int inter_guild_parse_frommap(int fd);
int inter_guild_sql_init();
+void inter_guild_sql_final();
int inter_guild_mapif_init(int fd);
int inter_guild_leave(int guild_id,int account_id,int char_id);
diff --git a/src/char_sql/int_party.c b/src/char_sql/int_party.c
index b2528a42d..430385110 100644
--- a/src/char_sql/int_party.c
+++ b/src/char_sql/int_party.c
@@ -3,15 +3,12 @@
// SQL conversion by hack
//
-#include "char.h"
-#include "strlib.h"
-#include "socket.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-
-
-#define mysql_query(_x, _y) debug_mysql_query(__FILE__, __LINE__, _x, _y)
+#include "char.h"
+#include "../common/strlib.h"
+#include "socket.h"
static struct party *party_pt;
static int party_newid=100;
@@ -20,29 +17,31 @@ int mapif_party_broken(int party_id,int flag);
int party_check_empty(struct party *p);
int mapif_parse_PartyLeave(int fd,int party_id,int account_id);
+#define mysql_query(_x, _y) debug_mysql_query(__FILE__, __LINE__, _x, _y)
+
// Save party to mysql
int inter_party_tosql(int party_id,struct party *p)
{
// 'party' ('party_id','name','exp','item','leader')
-
+
char t_name[100];
char t_member[24];
int party_member = 0, party_online_member = 0;
int party_exist = 0;
int leader_id = 0;
int i = 0;
-
+
printf("(\033[1;64m%d\033[0m) Request save party - ",party_id);
-
+
jstrescapecpy(t_name, p->name);
-
+
if (p==NULL || party_id==0 || p->party_id ==0 || party_id!=p->party_id) {
printf("- Party pointer or party_id error \n");
return 0;
}
-
- // Check if party exists
- sprintf(tmp_sql,"SELECT count(*) FROM `%s` WHERE `party_id`='%d'",party_db, party_id);
+
+ // Check if party exists
+ sprintf(tmp_sql,"SELECT count(*) FROM `%s` WHERE `party_id`='%d'",party_db, party_id); // TBR
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
return 0;
@@ -57,7 +56,7 @@ int inter_party_tosql(int party_id,struct party *p)
if (party_exist >0){
// Check members in party
- sprintf(tmp_sql,"SELECT count(*) FROM `%s` WHERE `party_id`='%d'",char_db, party_id);
+ sprintf(tmp_sql,"SELECT count(*) FROM `%s` WHERE `party_id`='%d'",char_db, party_id); // TBR
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
return 0;
@@ -65,22 +64,22 @@ int inter_party_tosql(int party_id,struct party *p)
sql_res = mysql_store_result(&mysql_handle) ;
if (sql_res!=NULL && mysql_num_rows(sql_res)>0) {
sql_row = mysql_fetch_row(sql_res);
-
+
party_member = atoi (sql_row[0]);
// printf("- Check members in party %d : %d \n",party_id,party_member);
}
mysql_free_result(sql_res) ; //resource free
-
+
party_online_member = 0;
i=0;
while (i<MAX_PARTY){
if (p->member[i].account_id>0) party_online_member++;
i++;
}
-
+
//if (party_online_member==0) printf("- No member online \n"); else printf("- Some member %d online \n", party_online_member);
-
+
if (party_member <= 0 && party_online_member == 0) {
// Delete the party, if has no member.
@@ -93,29 +92,29 @@ int inter_party_tosql(int party_id,struct party *p)
return 0;
} else {
// Update party information, if exists
-
+
int i=0;
-
+
for (i=0;i<MAX_PARTY;i++){
if (p->member[i].account_id>0){
- sprintf(tmp_sql,"UPDATE `%s` SET `party_id`='%d', `online`='%d' WHERE `account_id`='%d' AND `name`='%s'",
- char_db, party_id, p->member[i].online, p->member[i].account_id,jstrescapecpy(t_member,p->member[i].name));
+ sprintf(tmp_sql,"UPDATE `%s` SET `party_id`='%d' WHERE `account_id`='%d' AND `name`='%s'",
+ char_db, party_id, p->member[i].account_id,jstrescapecpy(t_member,p->member[i].name));
//printf("%s",tmp_sql);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (update `char`)- %s\n", mysql_error(&mysql_handle) );
}
}
}
-
-
+
+
sprintf(tmp_sql,"UPDATE `%s` SET `name`='%s', `exp`='%d', `item`='%d', `leader_id`=`leader_id` WHERE `party_id`='%d'",
- party_db, t_name,p->exp,p->item,party_id);
+ party_db, t_name,p->exp,p->item,party_id);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (inset/update `party`)- %s\n", mysql_error(&mysql_handle) );
}
-
+
// printf("- Update party %d information \n",party_id);
}
} else {
@@ -129,18 +128,18 @@ int inter_party_tosql(int party_id,struct party *p)
printf("DB server Error (inset/update `party`)- %s\n", mysql_error(&mysql_handle) );
return 0;
}
-
- sprintf(tmp_sql,"UPDATE `%s` SET `party_id`='%d', `online`='1' WHERE `account_id`='%d' AND `name`='%s'",
- char_db, party_id,leader_id, jstrescapecpy(t_member,p->member[i].name));
+
+ sprintf(tmp_sql,"UPDATE `%s` SET `party_id`='%d' WHERE `account_id`='%d' AND `name`='%s'",
+ char_db, party_id,leader_id, jstrescapecpy(t_member,p->member[i].name));
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (inset/update `party`)- %s\n", mysql_error(&mysql_handle) );
}
-
- //printf("- Insert new party %d \n",party_id);
+
+ //printf("- Insert new party %d \n",party_id);
}
-
+
printf("Party save success\n");
- return 0;
+ return 0;
}
@@ -149,15 +148,15 @@ int inter_party_fromsql(int party_id,struct party *p)
{
int leader_id=0;
printf("(\033[1;64m%d\033[0m) Request load party - ",party_id);
-
+
memset(p, 0, sizeof(struct party));
-
- sprintf(tmp_sql,"SELECT `party_id`, `name`,`exp`,`item`, `leader_id` FROM `%s` WHERE `party_id`='%d'",party_db, party_id);
+
+ sprintf(tmp_sql,"SELECT `party_id`, `name`,`exp`,`item`, `leader_id` FROM `%s` WHERE `party_id`='%d'",party_db, party_id); // TBR
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (select `party`)- %s\n", mysql_error(&mysql_handle) );
return 0;
}
-
+
sql_res = mysql_store_result(&mysql_handle) ;
if (sql_res!=NULL && mysql_num_rows(sql_res)>0) {
sql_row = mysql_fetch_row(sql_res);
@@ -172,11 +171,11 @@ int inter_party_fromsql(int party_id,struct party *p)
// printf("- Cannot find party %d \n",party_id);
return 0;
}
-
+
mysql_free_result(sql_res);
-
+
// Load members
- sprintf(tmp_sql,"SELECT `account_id`, `name`,`base_level`,`last_map`,`online` FROM `%s` WHERE `party_id`='%d'",char_db, party_id);
+ sprintf(tmp_sql,"SELECT `account_id`, `name`,`base_level`,`last_map`,`online` FROM `%s` WHERE `party_id`='%d'",char_db, party_id); // TBR
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (select `party`)- %s\n", mysql_error(&mysql_handle) );
return 0;
@@ -196,25 +195,20 @@ int inter_party_fromsql(int party_id,struct party *p)
// printf("- %d members found in party %d \n",i,party_id);
}
mysql_free_result(sql_res);
-
-
+
+
printf("Party load success\n");
return 0;
-
+
}
int inter_party_sql_init(){
int i;
-
+
//memory alloc
printf("interserver party memory initialize.... (%d byte)\n",sizeof(struct party));
- party_pt = calloc(sizeof(struct party), 1);
-
- sprintf(tmp_sql,"UPDATE `%s` SET `online`='0'", char_db);
- if(mysql_query(&mysql_handle, tmp_sql) ) {
- printf("DB server Error (update `char`)- %s\n", mysql_error(&mysql_handle) );
- }
-
+ party_pt = (struct party*)aCalloc(sizeof(struct party), 1);
+
sprintf (tmp_sql , "SELECT count(*) FROM `%s`",party_db);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
@@ -231,18 +225,22 @@ int inter_party_sql_init(){
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
}
-
+
sql_res = mysql_store_result(&mysql_handle) ;
-
+
sql_row = mysql_fetch_row(sql_res);
party_newid = atoi (sql_row[0])+1;
mysql_free_result(sql_res);
}
-
+
printf("set party_newid: %d.......\n",party_newid);
-
+
return 0;
}
+void inter_party_sql_final(){
+ if (party_pt) aFree(party_pt);
+ return;
+}
// Search for the party according to its name
@@ -251,8 +249,8 @@ struct party* search_partyname(char *str)
struct party *p=NULL;
int leader_id = 0;
char t_name[24];
-
- sprintf(tmp_sql,"SELECT `party_id`, `name`,`exp`,`item`,`leader_id` FROM `%s` WHERE `name`='%s'",party_db, jstrescapecpy(t_name,str));
+
+ sprintf(tmp_sql,"SELECT `party_id`, `name`,`exp`,`item`,`leader_id` FROM `%s` WHERE `name`='%s'",party_db, jstrescapecpy(t_name,str));
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (select `party`)- %s\n", mysql_error(&mysql_handle) );
}
@@ -295,16 +293,32 @@ struct party* search_partyname(char *str)
// EXPŒö•½•ª”z‚Å‚«‚é‚©ƒ`ƒFƒbƒN
int party_check_exp_share(struct party *p)
{
- int i;
- int maxlv=0,minlv=0x7fffffff;
- for(i=0;i<MAX_PARTY;i++){
- int lv=p->member[i].lv;
- if( p->member[i].online ){
- if( lv < minlv ) minlv=lv;
- if( maxlv < lv ) maxlv=lv;
- }
- }
- return (maxlv==0 || maxlv-minlv<=party_share_level);
+ int i, dudes=0;
+ int pl1=0,pl2=0,pl3=0;
+ int maxlv=0,minlv=0x7fffffff;
+ for(i=0;i<MAX_PARTY;i++){
+ int lv=p->member[i].lv;
+ if (!lv) continue;
+ if( p->member[i].online ){
+ if( lv < minlv ) minlv=lv;
+ if( maxlv < lv ) maxlv=lv;
+ if( lv >= 70 ) dudes+=1000;
+ dudes++;
+ }
+ }
+ if((dudes/1000 >= 2) && (dudes%1000 == 3) && (!strcmp(p->member[0].map,p->member[1].map)) && (!strcmp(p->member[1].map,p->member[2].map))) {
+ pl1=char_nick2id(p->member[0].name);
+ pl2=char_nick2id(p->member[1].name);
+ pl3=char_nick2id(p->member[2].name);
+ printf("PARTY: group of 3 Id1 %d lv %d name %s Id2 %d lv %d name %s Id3 %d lv %d name %s\n",pl1,p->member[0].lv,p->member[0].name,pl2,p->member[1].lv,p->member[1].name,pl3,p->member[2].lv,p->member[2].name);
+ if (char_married(pl1,pl2) && char_child(pl1,pl3))
+ return 1;
+ if (char_married(pl1,pl3) && char_child(pl1,pl2))
+ return 1;
+ if (char_married(pl2,pl3) && char_child(pl2,pl1))
+ return 1;
+ }
+ return (maxlv==0 || maxlv-minlv<=party_share_level);
}
// Is there any member in the party?
int party_check_empty(struct party *p)
@@ -441,7 +455,7 @@ int mapif_party_broken(int party_id,int flag)
return 0;
}
// ƒp[ƒeƒB“à”­Œ¾
-int mapif_party_message(int party_id,int account_id,char *mes,int len)
+int mapif_party_message(int party_id,int account_id,char *mes,int len, int sfd)
{
unsigned char buf[512];
WBUFW(buf,0)=0x3827;
@@ -449,7 +463,7 @@ int mapif_party_message(int party_id,int account_id,char *mes,int len)
WBUFL(buf,4)=party_id;
WBUFL(buf,8)=account_id;
memcpy(WBUFP(buf,12),mes,len);
- mapif_sendall(buf,len+12);
+ mapif_sendallwos(sfd, buf,len+12);
return 0;
}
@@ -458,7 +472,7 @@ int mapif_party_message(int party_id,int account_id,char *mes,int len)
// Create Party
-int mapif_parse_CreateParty(int fd,int account_id,char *name,char *nick,char *map,int lv)
+int mapif_parse_CreateParty(int fd,int account_id,char *name,char *nick,char *map,int lv, int item, int item2)
{
struct party *p;
if( (p=search_partyname(name))!=NULL){
@@ -476,19 +490,24 @@ int mapif_parse_CreateParty(int fd,int account_id,char *name,char *nick,char *ma
p->party_id=party_newid++;
memcpy(p->name,name,24);
p->exp=0;
- p->item=0;
+ p->item=item;
+ //<item1>ƒAƒCƒeƒ€?W•û–@B0‚ÅŒÂl•ÊA1‚Ńp?ƒeƒBŒö—L
+ //<item2>ƒAƒCƒeƒ€•ª”z•û–@B0‚ÅŒÂl•ÊA1‚Ńp?ƒeƒB‚ɋϓ™•ª”z
+ //difference between "collection" and "distribution" is...? ^^;
+ p->itemc = 0;
+
p->member[0].account_id=account_id;
memcpy(p->member[0].name,nick,24);
memcpy(p->member[0].map,map,16);
p->member[0].leader=1;
p->member[0].online=1;
p->member[0].lv=lv;
-
+
inter_party_tosql(p->party_id,p);
-
+
mapif_party_created(fd,account_id,p);
mapif_party_info(fd,p);
-
+
return 0;
}
// ƒp[ƒeƒBî•ñ—v‹
@@ -500,7 +519,7 @@ int mapif_parse_PartyInfo(int fd,int party_id)
return 0;
}
inter_party_fromsql(party_id, p);
-
+
if(p->party_id >= 0)
mapif_party_info(fd,p);
else
@@ -512,23 +531,23 @@ int mapif_parse_PartyAddMember(int fd,int party_id,int account_id,char *nick,cha
{
struct party *p;
int i;
-
+
p = party_pt;
if(p==NULL){
printf("int_party: out of memory !\n");
return 0;
}
inter_party_fromsql(party_id, p);
-
+
if(p->party_id <= 0){
mapif_party_memberadded(fd,party_id,account_id,1);
return 0;
}
-
+
for(i=0;i<MAX_PARTY;i++){
if(p->member[i].account_id==0){
int flag=0;
-
+
p->member[i].account_id=account_id;
memcpy(p->member[i].name,nick,24);
memcpy(p->member[i].map,map,16);
@@ -544,7 +563,7 @@ int mapif_parse_PartyAddMember(int fd,int party_id,int account_id,char *nick,cha
}
if(flag)
mapif_party_optionchanged(fd,p,0,0);
-
+
inter_party_tosql(party_id, p);
return 0;
}
@@ -558,25 +577,25 @@ int mapif_parse_PartyChangeOption(int fd,int party_id,int account_id,int exp,int
{
struct party *p;
int flag=0;
-
+
p = party_pt;
if(p==NULL){
printf("int_party: out of memory !\n");
return 0;
}
-
+
inter_party_fromsql(party_id, p);
-
+
if(p->party_id <= 0){
return 0;
}
-
+
p->exp=exp;
if( exp>0 && !party_check_exp_share(p) ){
flag|=0x01;
p->exp=0;
}
-
+
p->item=item;
mapif_party_optionchanged(fd,p,account_id,flag);
@@ -592,27 +611,27 @@ int mapif_parse_PartyLeave(int fd,int party_id,int account_id)
printf("int_party: out of memory !\n");
return 0;
}
-
+
inter_party_fromsql(party_id, p);
-
+
if(p->party_id >= 0){
int i,j;
for(i=0;i<MAX_PARTY;i++){
-
+
if(p->member[i].account_id==account_id){
//printf("p->member[i].account_id = %d , account_id = %d \n",p->member[i].account_id,account_id);
mapif_party_leaved(party_id,account_id,p->member[i].name);
-
-
-
+
+
+
// Update char information, does the name need encoding?
- sprintf(tmp_sql,"UPDATE `%s` SET `party_id`='0', `online`='1' WHERE `party_id`='%d' AND `name`='%s'",
+ sprintf(tmp_sql,"UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d' AND `name`='%s'",
char_db, party_id, jstrescapecpy(t_member,p->member[i].name));
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (update `char`)- %s\n", mysql_error(&mysql_handle) );
}
-// printf("Delete member %s from MySQL \n", p->member[i].name);
-
+// printf("Delete member %s from MySQL \n", p->member[i].name);
+
if (p->member[i].leader==1){
for(j=0;j<MAX_PARTY;j++)
{
@@ -620,12 +639,12 @@ int mapif_parse_PartyLeave(int fd,int party_id,int account_id)
if(p->member[j].account_id>0&&j!=i){
mapif_party_leaved(party_id,p->member[j].account_id,p->member[j].name);
// Update char information, does the name need encoding?
- sprintf(tmp_sql,"UPDATE `%s` SET `party_id`='0', `online`='1' WHERE `party_id`='%d' AND `name`='%s'",
+ sprintf(tmp_sql,"UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d' AND `name`='%s'",
char_db, party_id, jstrescapecpy(t_member,p->member[i].name));
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (update `char`)- %s\n", mysql_error(&mysql_handle) );
}
-// printf("Delete member %s from MySQL \n", p->member[j].name);
+// printf("Delete member %s from MySQL \n", p->member[j].name);
}
}
// Delete the party, if has no member.
@@ -634,9 +653,9 @@ int mapif_parse_PartyLeave(int fd,int party_id,int account_id)
printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
}
// printf("Leader breaks party %d \n",party_id);
- memset(p, 0, sizeof(struct party));
+ memset(p, 0, sizeof(struct party));
}else memset(&p->member[i],0,sizeof(struct party_member));
-
+
break;
}
@@ -648,8 +667,8 @@ int mapif_parse_PartyLeave(int fd,int party_id,int account_id)
inter_party_tosql(party_id,p); // Break the party if no member
*/
}else{
- sprintf(tmp_sql,"UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d' AND `account_id`='%d' AND `online`='1'",
- char_db, party_id, account_id);
+ sprintf(tmp_sql,"UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d' AND `account_id`='%d' AND `online`='1'",
+ char_db, party_id, account_id);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (update `char`)- %s\n", mysql_error(&mysql_handle) );
}
@@ -661,21 +680,21 @@ int mapif_parse_PartyChangeMap(int fd,int party_id,int account_id,char *map,int
{
struct party *p;
int i;
-
+
p = party_pt;
if(p==NULL){
printf("int_party: out of memory !\n");
return 0;
}
inter_party_fromsql(party_id, p);
-
+
if(p->party_id <= 0){
return 0;
}
for(i=0;i<MAX_PARTY;i++){
if(p->member[i].account_id==account_id){
int flag=0;
-
+
memcpy(p->member[i].map,map,16);
p->member[i].online=online;
p->member[i].lv=lv;
@@ -697,27 +716,27 @@ int mapif_parse_PartyChangeMap(int fd,int party_id,int account_id,char *map,int
int mapif_parse_BreakParty(int fd,int party_id)
{
struct party *p;
-
+
p = party_pt;
if(p==NULL){
printf("int_party: out of memory !\n");
return 0;
}
-
+
inter_party_fromsql(party_id, p);
-
+
if(p->party_id <= 0){
return 0;
}
inter_party_tosql(party_id,p);
-
+
mapif_party_broken(fd,party_id);
return 0;
}
// ƒp[ƒeƒBƒƒbƒZ[ƒW‘—M
int mapif_parse_PartyMessage(int fd,int party_id,int account_id,char *mes,int len)
{
- return mapif_party_message(party_id,account_id,mes,len);
+ return mapif_party_message(party_id,account_id,mes,len, fd);
}
// ƒp[ƒeƒBƒ`ƒFƒbƒN—v‹
int mapif_parse_PartyCheck(int fd,int party_id,int account_id,char *nick)
@@ -733,15 +752,15 @@ int mapif_parse_PartyCheck(int fd,int party_id,int account_id,char *nick)
int inter_party_parse_frommap(int fd)
{
switch(RFIFOW(fd,0)){
- case 0x3020: mapif_parse_CreateParty(fd,RFIFOL(fd,2),RFIFOP(fd,6),RFIFOP(fd,30),RFIFOP(fd,54),RFIFOW(fd,70)); break;
+ case 0x3020: mapif_parse_CreateParty(fd,RFIFOL(fd,2),(char*)RFIFOP(fd,6),(char*)RFIFOP(fd,30),(char*)RFIFOP(fd,54),RFIFOW(fd,70), RFIFOB(fd,72), RFIFOB(fd,73)); break;
case 0x3021: mapif_parse_PartyInfo(fd,RFIFOL(fd,2)); break;
- case 0x3022: mapif_parse_PartyAddMember(fd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOP(fd,10),RFIFOP(fd,34),RFIFOW(fd,50)); break;
+ case 0x3022: mapif_parse_PartyAddMember(fd,RFIFOL(fd,2),RFIFOL(fd,6),(char*)RFIFOP(fd,10),(char*)RFIFOP(fd,34),RFIFOW(fd,50)); break;
case 0x3023: mapif_parse_PartyChangeOption(fd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOW(fd,10),RFIFOW(fd,12)); break;
case 0x3024: mapif_parse_PartyLeave(fd,RFIFOL(fd,2),RFIFOL(fd,6)); break;
- case 0x3025: mapif_parse_PartyChangeMap(fd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOP(fd,10),RFIFOB(fd,26),RFIFOW(fd,27)); break;
+ case 0x3025: mapif_parse_PartyChangeMap(fd,RFIFOL(fd,2),RFIFOL(fd,6),(char*)RFIFOP(fd,10),RFIFOB(fd,26),RFIFOW(fd,27)); break;
case 0x3026: mapif_parse_BreakParty(fd,RFIFOL(fd,2)); break;
- case 0x3027: mapif_parse_PartyMessage(fd,RFIFOL(fd,4),RFIFOL(fd,8),RFIFOP(fd,12),RFIFOW(fd,2)-12); break;
- case 0x3028: mapif_parse_PartyCheck(fd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOP(fd,10)); break;
+ case 0x3027: mapif_parse_PartyMessage(fd,RFIFOL(fd,4),RFIFOL(fd,8),(char*)RFIFOP(fd,12),RFIFOW(fd,2)-12); break;
+ case 0x3028: mapif_parse_PartyCheck(fd,RFIFOL(fd,2),RFIFOL(fd,6),(char*)RFIFOP(fd,10)); break;
default:
return 0;
}
diff --git a/src/char_sql/int_party.h b/src/char_sql/int_party.h
index 04f71c881..686d70b04 100644
--- a/src/char_sql/int_party.h
+++ b/src/char_sql/int_party.h
@@ -3,6 +3,7 @@
int inter_party_parse_frommap(int fd);
int inter_party_sql_init();
+void inter_party_sql_final();
int inter_party_leave(int party_id,int account_id);
#endif
diff --git a/src/char_sql/int_pet.c b/src/char_sql/int_pet.c
index 7f2ed2a7c..ea1fed67d 100644
--- a/src/char_sql/int_pet.c
+++ b/src/char_sql/int_pet.c
@@ -2,13 +2,13 @@
// original code from athena
// SQL conversion by Jioh L. Jung
//
-#include "char.h"
-#include "strlib.h"
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include "char.h"
+#include "../common/strlib.h"
+
struct s_pet *pet_pt;
static int pet_newid = 100;
@@ -18,11 +18,11 @@ static int pet_newid = 100;
int inter_pet_tosql(int pet_id, struct s_pet *p) {
//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`)
char t_name[100];
-
+
printf("request save pet: %d.......\n",pet_id);
-
+
jstrescapecpy(t_name, p->name);
-
+
if(p->hungry < 0)
p->hungry = 0;
else if(p->hungry > 100)
@@ -36,32 +36,32 @@ int inter_pet_tosql(int pet_id, struct s_pet *p) {
printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
}
sql_res = mysql_store_result(&mysql_handle) ;
- if (sql_res!=NULL && mysql_num_rows(sql_res)>0)
+ if (sql_res!=NULL && mysql_num_rows(sql_res)>0)
//row reside -> updating
sprintf(tmp_sql, "UPDATE `%s` SET `class`='%d',`name`='%s',`account_id`='%d',`char_id`='%d',`level`='%d',`egg_id`='%d',`equip`='%d',`intimate`='%d',`hungry`='%d',`rename_flag`='%d',`incuvate`='%d' WHERE `pet_id`='%d'",
- pet_db, p->class, t_name, p->account_id, p->char_id, p->level, p->egg_id,
+ pet_db, p->class_, t_name, p->account_id, p->char_id, p->level, p->egg_id,
p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate, p->pet_id);
else //no row -> insert
sprintf(tmp_sql,"INSERT INTO `%s` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`) VALUES ('%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
- pet_db, pet_id, p->class, t_name, p->account_id, p->char_id, p->level, p->egg_id,
+ pet_db, pet_id, p->class_, t_name, p->account_id, p->char_id, p->level, p->egg_id,
p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate);
mysql_free_result(sql_res) ; //resource free
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (inset/update `pet`)- %s\n", mysql_error(&mysql_handle) );
}
-
+
printf("pet save success.......\n");
return 0;
}
int inter_pet_fromsql(int pet_id, struct s_pet *p){
-
+
printf("request load pet: %d.......\n",pet_id);
-
+
memset(p, 0, sizeof(struct s_pet));
-
+
//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`)
-
+
sprintf(tmp_sql,"SELECT `pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate` FROM `%s` WHERE `pet_id`='%d'",pet_db, pet_id);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (select `pet`)- %s\n", mysql_error(&mysql_handle) );
@@ -70,9 +70,9 @@ int inter_pet_fromsql(int pet_id, struct s_pet *p){
sql_res = mysql_store_result(&mysql_handle) ;
if (sql_res!=NULL && mysql_num_rows(sql_res)>0) {
sql_row = mysql_fetch_row(sql_res);
-
+
p->pet_id = pet_id;
- p->class = atoi(sql_row[1]);
+ p->class_ = atoi(sql_row[1]);
memcpy(p->name, sql_row[2],24);
p->account_id = atoi(sql_row[3]);
p->char_id = atoi(sql_row[4]);
@@ -92,20 +92,20 @@ int inter_pet_fromsql(int pet_id, struct s_pet *p){
p->intimate = 0;
else if(p->intimate > 1000)
p->intimate = 1000;
-
+
mysql_free_result(sql_res);
-
+
printf("pet load success.......\n");
return 0;
}
//----------------------------------------------
-
+
int inter_pet_sql_init(){
int i;
-
+
//memory alloc
printf("interserver pet memory initialize.... (%d byte)\n",sizeof(struct s_pet));
- pet_pt = calloc(sizeof(struct s_pet), 1);
+ pet_pt = (struct s_pet*)aCalloc(sizeof(struct s_pet), 1);
sprintf (tmp_sql , "SELECT count(*) FROM `%s`", pet_db);
if(mysql_query(&mysql_handle, tmp_sql) ) {
@@ -124,22 +124,26 @@ int inter_pet_sql_init(){
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
}
-
+
sql_res = mysql_store_result(&mysql_handle) ;
-
+
sql_row = mysql_fetch_row(sql_res);
pet_newid = atoi (sql_row[0])+1; //should SET MAX existing PET ID + 1 [Lupus]
mysql_free_result(sql_res);
}
-
+
printf("set pet_newid: %d.......\n",pet_newid);
-
+
return 0;
}
+void inter_pet_sql_final(){
+ if (pet_pt) aFree(pet_pt);
+ return;
+}
//----------------------------------
int inter_pet_delete(int pet_id){
printf("request delete pet: %d.......\n",pet_id);
-
+
sprintf(tmp_sql,"DELETE FROM `%s` WHERE `pet_id`='%d'",pet_db, pet_id);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
@@ -215,7 +219,7 @@ int mapif_create_pet(int fd, int account_id, int char_id, short pet_class, short
pet_pt->account_id = account_id;
pet_pt->char_id = char_id;
}
- pet_pt->class = pet_class;
+ pet_pt->class_ = pet_class;
pet_pt->level = pet_lv;
pet_pt->egg_id = pet_egg_id;
pet_pt->equip = pet_equip;
@@ -232,19 +236,19 @@ int mapif_create_pet(int fd, int account_id, int char_id, short pet_class, short
pet_pt->intimate = 0;
else if(pet_pt->intimate > 1000)
pet_pt->intimate = 1000;
-
+
inter_pet_tosql(pet_pt->pet_id,pet_pt);
-
+
mapif_pet_created(fd, account_id, pet_pt);
-
+
return 0;
}
int mapif_load_pet(int fd, int account_id, int char_id, int pet_id){
memset(pet_pt, 0, sizeof(struct s_pet));
-
+
inter_pet_fromsql(pet_id, pet_pt);
-
+
if(pet_pt!=NULL) {
if(pet_pt->incuvate == 1) {
pet_pt->account_id = pet_pt->char_id = 0;
@@ -267,7 +271,7 @@ int mapif_save_pet(int fd, int account_id, struct s_pet *data) {
if(sizeof(struct s_pet)!=len-8) {
printf("inter pet: data size error %d %d\n", sizeof(struct s_pet), len-8);
}
-
+
else{
if(data->hungry < 0)
data->hungry = 0;
@@ -292,7 +296,7 @@ int mapif_delete_pet(int fd, int pet_id){
int mapif_parse_CreatePet(int fd){
mapif_create_pet(fd, RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOW(fd, 10), RFIFOW(fd, 12), RFIFOW(fd, 14), RFIFOW(fd, 16), RFIFOL(fd, 18),
- RFIFOL(fd, 20), RFIFOB(fd, 22), RFIFOB(fd, 23), RFIFOP(fd, 24));
+ RFIFOL(fd, 20), RFIFOB(fd, 22), RFIFOB(fd, 23), (char*)RFIFOP(fd, 24));
return 0;
}
diff --git a/src/char_sql/int_pet.h b/src/char_sql/int_pet.h
index b6e3f1bbf..39f127262 100644
--- a/src/char_sql/int_pet.h
+++ b/src/char_sql/int_pet.h
@@ -2,6 +2,7 @@
#define _INT_PET_H_
int inter_pet_init();
+void inter_pet_sql_final();
int inter_pet_save();
int inter_pet_delete(int pet_id);
diff --git a/src/char_sql/int_storage.c b/src/char_sql/int_storage.c
index 18100e02a..c13c782a6 100644
--- a/src/char_sql/int_storage.c
+++ b/src/char_sql/int_storage.c
@@ -2,62 +2,46 @@
// original code from athena
// SQL conversion by Jioh L. Jung
//
-#include "char.h"
-#include "itemdb.h"
#include <string.h>
#include <stdlib.h>
+#include "char.h"
+#include "itemdb.h"
+
#define STORAGE_MEMINC 16
// reset by inter_config_read()
struct storage *storage_pt=NULL;
struct guild_storage *guild_storage_pt=NULL;
-
#define mysql_query(_x, _y) debug_mysql_query(__FILE__, __LINE__, _x, _y)
// storage data -> DB conversion
int storage_tosql(int account_id,struct storage *p){
int i;
- int eqcount=1;
- int noteqcount=1;
- struct itemtemp mapitem;
+// int eqcount=1;
+// int noteqcount=1;
+ int count=0;
+ struct itemtmp mapitem[MAX_GUILD_STORAGE];
for(i=0;i<MAX_STORAGE;i++){
- if(p->storage[i].nameid>0){
- if(itemdb_isequip(p->storage[i].nameid)==1){
- mapitem.equip[eqcount].flag=0;
- mapitem.equip[eqcount].id = p->storage[i].id;
- mapitem.equip[eqcount].nameid=p->storage[i].nameid;
- mapitem.equip[eqcount].amount = p->storage[i].amount;
- mapitem.equip[eqcount].equip = p->storage[i].equip;
- mapitem.equip[eqcount].identify = p->storage[i].identify;
- mapitem.equip[eqcount].refine = p->storage[i].refine;
- mapitem.equip[eqcount].attribute = p->storage[i].attribute;
- mapitem.equip[eqcount].card[0] = p->storage[i].card[0];
- mapitem.equip[eqcount].card[1] = p->storage[i].card[1];
- mapitem.equip[eqcount].card[2] = p->storage[i].card[2];
- mapitem.equip[eqcount].card[3] = p->storage[i].card[3];
- eqcount++;
- }
- else if(itemdb_isequip(p->storage[i].nameid)==0){
- mapitem.notequip[noteqcount].flag=0;
- mapitem.notequip[noteqcount].id = p->storage[i].id;
- mapitem.notequip[noteqcount].nameid=p->storage[i].nameid;
- mapitem.notequip[noteqcount].amount = p->storage[i].amount;
- mapitem.notequip[noteqcount].equip = p->storage[i].equip;
- mapitem.notequip[noteqcount].identify = p->storage[i].identify;
- mapitem.notequip[noteqcount].refine = p->storage[i].refine;
- mapitem.notequip[noteqcount].attribute = p->storage[i].attribute;
- mapitem.notequip[noteqcount].card[0] = p->storage[i].card[0];
- mapitem.notequip[noteqcount].card[1] = p->storage[i].card[1];
- mapitem.notequip[noteqcount].card[2] = p->storage[i].card[2];
- mapitem.notequip[noteqcount].card[3] = p->storage[i].card[3];
- noteqcount++;
- }
+ if(p->storage_[i].nameid>0){
+ mapitem[count].flag=0;
+ mapitem[count].id = p->storage_[i].id;
+ mapitem[count].nameid=p->storage_[i].nameid;
+ mapitem[count].amount = p->storage_[i].amount;
+ mapitem[count].equip = p->storage_[i].equip;
+ mapitem[count].identify = p->storage_[i].identify;
+ mapitem[count].refine = p->storage_[i].refine;
+ mapitem[count].attribute = p->storage_[i].attribute;
+ mapitem[count].card[0] = p->storage_[i].card[0];
+ mapitem[count].card[1] = p->storage_[i].card[1];
+ mapitem[count].card[2] = p->storage_[i].card[2];
+ mapitem[count].card[3] = p->storage_[i].card[3];
+ count++;
}
}
- memitemdata_to_sql(mapitem, eqcount, noteqcount, account_id,TABLE_STORAGE);
+ memitemdata_to_sql(mapitem, count, account_id,TABLE_STORAGE);
//printf ("storage dump to DB - id: %d (total: %d)\n", account_id, j);
return 0;
@@ -66,36 +50,36 @@ int storage_tosql(int account_id,struct storage *p){
// DB -> storage data conversion
int storage_fromsql(int account_id, struct storage *p){
int i=0;
-
+
memset(p,0,sizeof(struct storage)); //clean up memory
p->storage_amount = 0;
p->account_id = account_id;
-
+
// storage {`account_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`}
sprintf(tmp_sql,"SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`card0`,`card1`,`card2`,`card3` FROM `%s` WHERE `account_id`='%d'",storage_db, account_id);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
}
sql_res = mysql_store_result(&mysql_handle) ;
-
+
if (sql_res) {
while((sql_row = mysql_fetch_row(sql_res))) { //start to fetch
- p->storage[i].id= atoi(sql_row[0]);
- p->storage[i].nameid= atoi(sql_row[1]);
- p->storage[i].amount= atoi(sql_row[2]);
- p->storage[i].equip= atoi(sql_row[3]);
- p->storage[i].identify= atoi(sql_row[4]);
- p->storage[i].refine= atoi(sql_row[5]);
- p->storage[i].attribute= atoi(sql_row[6]);
- p->storage[i].card[0]= atoi(sql_row[7]);
- p->storage[i].card[1]= atoi(sql_row[8]);
- p->storage[i].card[2]= atoi(sql_row[9]);
- p->storage[i].card[3]= atoi(sql_row[10]);
+ p->storage_[i].id= atoi(sql_row[0]);
+ p->storage_[i].nameid= atoi(sql_row[1]);
+ p->storage_[i].amount= atoi(sql_row[2]);
+ p->storage_[i].equip= atoi(sql_row[3]);
+ p->storage_[i].identify= atoi(sql_row[4]);
+ p->storage_[i].refine= atoi(sql_row[5]);
+ p->storage_[i].attribute= atoi(sql_row[6]);
+ p->storage_[i].card[0]= atoi(sql_row[7]);
+ p->storage_[i].card[1]= atoi(sql_row[8]);
+ p->storage_[i].card[2]= atoi(sql_row[9]);
+ p->storage_[i].card[3]= atoi(sql_row[10]);
p->storage_amount = ++i;
}
mysql_free_result(sql_res);
}
-
+
printf ("storage load complete from DB - id: %d (total: %d)\n", account_id, p->storage_amount);
return 1;
}
@@ -103,45 +87,29 @@ int storage_fromsql(int account_id, struct storage *p){
// Save guild_storage data to sql
int guild_storage_tosql(int guild_id, struct guild_storage *p){
int i;
- int eqcount=1;
- int noteqcount=1;
- struct itemtemp mapitem;
+// int eqcount=1;
+// int noteqcount=1;
+ int count=0;
+ struct itemtmp mapitem[MAX_GUILD_STORAGE];
for(i=0;i<MAX_GUILD_STORAGE;i++){
- if(p->storage[i].nameid>0){
- if(itemdb_isequip(p->storage[i].nameid)==1){
- mapitem.equip[eqcount].flag=0;
- mapitem.equip[eqcount].id = p->storage[i].id;
- mapitem.equip[eqcount].nameid=p->storage[i].nameid;
- mapitem.equip[eqcount].amount = p->storage[i].amount;
- mapitem.equip[eqcount].equip = p->storage[i].equip;
- mapitem.equip[eqcount].identify = p->storage[i].identify;
- mapitem.equip[eqcount].refine = p->storage[i].refine;
- mapitem.equip[eqcount].attribute = p->storage[i].attribute;
- mapitem.equip[eqcount].card[0] = p->storage[i].card[0];
- mapitem.equip[eqcount].card[1] = p->storage[i].card[1];
- mapitem.equip[eqcount].card[2] = p->storage[i].card[2];
- mapitem.equip[eqcount].card[3] = p->storage[i].card[3];
- eqcount++;
- }
- else if(itemdb_isequip(p->storage[i].nameid)==0){
- mapitem.notequip[noteqcount].flag=0;
- mapitem.notequip[noteqcount].id = p->storage[i].id;
- mapitem.notequip[noteqcount].nameid=p->storage[i].nameid;
- mapitem.notequip[noteqcount].amount = p->storage[i].amount;
- mapitem.notequip[noteqcount].equip = p->storage[i].equip;
- mapitem.notequip[noteqcount].identify = p->storage[i].identify;
- mapitem.notequip[noteqcount].refine = p->storage[i].refine;
- mapitem.notequip[noteqcount].attribute = p->storage[i].attribute;
- mapitem.notequip[noteqcount].card[0] = p->storage[i].card[0];
- mapitem.notequip[noteqcount].card[1] = p->storage[i].card[1];
- mapitem.notequip[noteqcount].card[2] = p->storage[i].card[2];
- mapitem.notequip[noteqcount].card[3] = p->storage[i].card[3];
- noteqcount++;
- }
+ if(p->storage_[i].nameid>0){
+ mapitem[count].flag=0;
+ mapitem[count].id = p->storage_[i].id;
+ mapitem[count].nameid=p->storage_[i].nameid;
+ mapitem[count].amount = p->storage_[i].amount;
+ mapitem[count].equip = p->storage_[i].equip;
+ mapitem[count].identify = p->storage_[i].identify;
+ mapitem[count].refine = p->storage_[i].refine;
+ mapitem[count].attribute = p->storage_[i].attribute;
+ mapitem[count].card[0] = p->storage_[i].card[0];
+ mapitem[count].card[1] = p->storage_[i].card[1];
+ mapitem[count].card[2] = p->storage_[i].card[2];
+ mapitem[count].card[3] = p->storage_[i].card[3];
+ count++;
}
}
- memitemdata_to_sql(mapitem, eqcount, noteqcount, guild_id,TABLE_GUILD_STORAGE);
+ memitemdata_to_sql(mapitem, count, guild_id,TABLE_GUILD_STORAGE);
printf ("guild storage save to DB - id: %d (total: %d)\n", guild_id,i);
return 0;
@@ -163,21 +131,23 @@ int guild_storage_fromsql(int guild_id, struct guild_storage *p){
printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
}
sql_res = mysql_store_result(&mysql_handle) ;
-
+
if (sql_res) {
while((sql_row = mysql_fetch_row(sql_res))) { //start to fetch
- p->storage[i].id= atoi(sql_row[0]);
- p->storage[i].nameid= atoi(sql_row[1]);
- p->storage[i].amount= atoi(sql_row[2]);
- p->storage[i].equip= atoi(sql_row[3]);
- p->storage[i].identify= atoi(sql_row[4]);
- p->storage[i].refine= atoi(sql_row[5]);
- p->storage[i].attribute= atoi(sql_row[6]);
- p->storage[i].card[0]= atoi(sql_row[7]);
- p->storage[i].card[1]= atoi(sql_row[8]);
- p->storage[i].card[2]= atoi(sql_row[9]);
- p->storage[i].card[3]= atoi(sql_row[10]);
+ p->storage_[i].id= atoi(sql_row[0]);
+ p->storage_[i].nameid= atoi(sql_row[1]);
+ p->storage_[i].amount= atoi(sql_row[2]);
+ p->storage_[i].equip= atoi(sql_row[3]);
+ p->storage_[i].identify= atoi(sql_row[4]);
+ p->storage_[i].refine= atoi(sql_row[5]);
+ p->storage_[i].attribute= atoi(sql_row[6]);
+ p->storage_[i].card[0]= atoi(sql_row[7]);
+ p->storage_[i].card[1]= atoi(sql_row[8]);
+ p->storage_[i].card[2]= atoi(sql_row[9]);
+ p->storage_[i].card[3]= atoi(sql_row[10]);
p->storage_amount = ++i;
+ if (i >= MAX_GUILD_STORAGE)
+ break;
}
mysql_free_result(sql_res);
}
@@ -188,17 +158,24 @@ int guild_storage_fromsql(int guild_id, struct guild_storage *p){
//---------------------------------------------------------
// storage data initialize
int inter_storage_sql_init(){
-
+
//memory alloc
printf("interserver storage memory initialize....(%d byte)\n",sizeof(struct storage));
- storage_pt=calloc(sizeof(struct storage), 1);
- guild_storage_pt=calloc(sizeof(struct guild_storage), 1);
+ storage_pt = (struct storage*)aCalloc(sizeof(struct storage), 1);
+ guild_storage_pt = (struct guild_storage*)aCalloc(sizeof(struct guild_storage), 1);
memset(storage_pt,0,sizeof(struct storage));
memset(guild_storage_pt,0,sizeof(struct guild_storage));
-
+
return 1;
}
-// ‘qŒÉƒf[ƒ^íœ
+// storage data finalize
+void inter_storage_sql_final()
+{
+ if (storage_pt) aFree(storage_pt);
+ if (guild_storage_pt) aFree(guild_storage_pt);
+ return;
+}
+// q?f[^?
int inter_storage_delete(int account_id)
{
sprintf(tmp_sql, "DELETE FROM `%s` WHERE `account_id`='%d'",storage_db, account_id);
@@ -243,7 +220,7 @@ int mapif_load_guild_storage(int fd,int account_id,int guild_id)
{
int guild_exist=0;
WFIFOW(fd,0)=0x3818;
-
+
// Check if guild exists, I may write a function for this later, coz I use it several times.
//printf("- Check if guild %d exists\n",g->guild_id);
sprintf(tmp_sql, "SELECT count(*) FROM `%s` WHERE `guild_id`='%d'",guild_db, guild_id);
@@ -257,7 +234,7 @@ int mapif_load_guild_storage(int fd,int account_id,int guild_id)
//printf("- Check if guild %d exists : %s\n",g->guild_id,((guild_exist==0)?"No":"Yes"));
}
mysql_free_result(sql_res) ; //resource free
-
+
if(guild_exist==1) {
guild_storage_fromsql(guild_id,guild_storage_pt);
WFIFOW(fd,2)=sizeof(struct guild_storage)+12;
@@ -296,7 +273,7 @@ int mapif_parse_LoadStorage(int fd){
int mapif_parse_SaveStorage(int fd){
int account_id=RFIFOL(fd,4);
int len=RFIFOW(fd,2);
-
+
if(sizeof(struct storage)!=len-8){
printf("inter storage: data size error %d %d\n",sizeof(struct storage),len-8);
}else{
@@ -335,7 +312,7 @@ int mapif_parse_SaveGuildStorage(int fd)
//printf("- Check if guild %d exists : %s\n",g->guild_id,((guild_exist==0)?"No":"Yes"));
}
mysql_free_result(sql_res) ; //resource free
-
+
if(guild_exist==1) {
memcpy(guild_storage_pt,RFIFOP(fd,12),sizeof(struct guild_storage));
guild_storage_tosql(guild_id,guild_storage_pt);
diff --git a/src/char_sql/int_storage.h b/src/char_sql/int_storage.h
index f9f37db3e..5541d1ed7 100644
--- a/src/char_sql/int_storage.h
+++ b/src/char_sql/int_storage.h
@@ -2,6 +2,7 @@
#define _INT_STORAGE_H_
int inter_storage_sql_init();
+void inter_storage_sql_final();
int inter_storage_delete(int account_id);
int inter_guild_storage_delete(int guild_id);
diff --git a/src/char_sql/inter.c b/src/char_sql/inter.c
index b50afb9d7..83fcc967f 100644
--- a/src/char_sql/inter.c
+++ b/src/char_sql/inter.c
@@ -7,7 +7,7 @@
#include <stdlib.h>
#include "char.h"
-#include "strlib.h"
+#include "../common/strlib.h"
#include "inter.h"
#include "int_party.h"
#include "int_guild.h"
@@ -15,8 +15,6 @@
#include "int_pet.h"
#include "lock.h"
-#define mysql_query(_x, _y) debug_mysql_query(__FILE__, __LINE__, _x, _y)
-
#define WISDATA_TTL (60*1000) // Wisƒf[ƒ^‚̶‘¶ŽžŠÔ(60•b)
#define WISDELLIST_MAX 256 // Wisƒf[ƒ^íœƒŠƒXƒg‚Ì—v‘f”
@@ -36,6 +34,11 @@ MYSQL_ROW sql_row ;
int sql_fields, sql_cnt;
char tmp_sql[65535];
+MYSQL lmysql_handle;
+char tmp_lsql[65535];
+MYSQL_RES* lsql_res ;
+MYSQL_ROW lsql_row ;
+
int char_server_port = 3306;
char char_server_ip[32] = "127.0.0.1";
char char_server_id[32] = "ragnarok";
@@ -64,7 +67,7 @@ int inter_send_packet_length[]={
int inter_recv_packet_length[]={
-1,-1, 7, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0,
- 72, 6,52,14, 10,29, 6,-1, 34, 0, 0, 0, 0, 0, 0, 0,
+ 74, 6,52,14, 10,29, 6,-1, 34, 0, 0, 0, 0, 0, 0, 0,
-1, 6,-1, 0, 55,19, 6,-1, 14,-1,-1,-1, 14,19,186,-1,
5, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -84,20 +87,20 @@ static int wis_dellist[WISDELLIST_MAX], wis_delnum;
//--------------------------------------------------------
// Save account_reg to sql (type=2)
int inter_accreg_tosql(int account_id,struct accreg *reg){
-
+
int j;
char temp_str[32];
if (account_id<=0) return 0;
reg->account_id=account_id;
-
+
//`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`)
sprintf(tmp_sql,"DELETE FROM `%s` WHERE `type`=2 AND `account_id`='%d'",reg_db, account_id);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (delete `global_reg_value`)- %s\n", mysql_error(&mysql_handle) );
}
-
+
if (reg->reg_num<=0) return 0;
-
+
for(j=0;j<reg->reg_num;j++){
if(reg->reg[j].str != NULL){
sprintf(tmp_sql,"INSERT INTO `%s` (`type`, `account_id`, `str`, `value`) VALUES (2,'%d', '%s','%d')",
@@ -117,7 +120,7 @@ int inter_accreg_fromsql(int account_id,struct accreg *reg)
if (reg==NULL) return 0;
memset(reg, 0, sizeof(struct accreg));
reg->account_id=account_id;
-
+
//`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`)
sprintf (tmp_sql, "SELECT `str`, `value` FROM `%s` WHERE `type`=2 AND `account_id`='%d'",reg_db, reg->account_id);
if(mysql_query(&mysql_handle, tmp_sql) ) {
@@ -126,7 +129,7 @@ int inter_accreg_fromsql(int account_id,struct accreg *reg)
sql_res = mysql_store_result(&mysql_handle);
if (sql_res) {
- for(j=0;(sql_row = mysql_fetch_row(sql_res));j++){
+ for(j=0;(sql_row = mysql_fetch_row(sql_res));j++){
memcpy(reg->reg[j].str, sql_row[0],32);
reg->reg[j].value = atoi(sql_row[1]);
}
@@ -141,7 +144,7 @@ int inter_accreg_sql_init()
{
CREATE(accreg_pt, struct accreg, 1);
return 0;
-
+
}
/*==========================================
@@ -187,7 +190,7 @@ int inter_config_read(const char *cfgName) {
}
//Logins information to be read from the inter_athena.conf
//for character deletion (checks email in the loginDB)
-
+
else if(strcmpi(w1,"login_server_ip")==0){
strcpy(login_server_ip, w2);
printf ("set login_server_ip : %s\n",w2);
@@ -223,7 +226,7 @@ int inter_config_read(const char *cfgName) {
}
}
fclose(fp);
-
+
printf ("success reading interserver configuration\n");
return 0;
@@ -241,7 +244,7 @@ int inter_log(char *fmt,...)
sprintf(tmp_sql,"INSERT INTO `%s` (`time`, `log`) VALUES (NOW(), '%s')",interlog_db, jstrescapecpy(temp_str,str));
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (insert `interlog`)- %s\n", mysql_error(&mysql_handle) );
- }
+ }
va_end(ap);
return 0;
@@ -252,37 +255,67 @@ int inter_log(char *fmt,...)
int inter_init(const char *file)
{
//int i;
-
+
printf ("interserver initialize...\n");
inter_config_read(file);
-
+
//DB connection initialized
mysql_init(&mysql_handle);
- printf("Connect to DB server....\n");
+ printf("Connect Character DB server.... (Character Server)\n");
if(!mysql_real_connect(&mysql_handle, char_server_ip, char_server_id, char_server_pw,
- char_server_db ,char_server_port, (char *)NULL, CLIENT_MULTI_STATEMENTS)) {
+ char_server_db ,char_server_port, (char *)NULL, 0)) {
//pointer check
printf("%s\n",mysql_error(&mysql_handle));
exit(1);
}
else {
- printf ("Connect Success!\n");
+ printf ("Connect Success! (Character Server)\n");
+ }
+
+ mysql_init(&lmysql_handle);
+ printf("Connect Character DB server.... (login server)\n");
+ if(!mysql_real_connect(&lmysql_handle, login_server_ip, login_server_id, login_server_pw,
+ login_server_db ,login_server_port, (char *)NULL, 0)) {
+ //pointer check
+ printf("%s\n",mysql_error(&lmysql_handle));
+ exit(1);
+ }else {
+ printf ("Connect Success! (Login Server)");
}
-
wis_db = numdb_init();
inter_guild_sql_init();
inter_storage_sql_init();
inter_party_sql_init();
-
+
inter_pet_sql_init();
inter_accreg_sql_init();
+ atexit(inter_final);
+
//printf ("interserver timer initializing : %d sec...\n",autosave_interval);
//i=add_timer_interval(gettick()+autosave_interval,inter_save_timer,0,0,autosave_interval);
return 0;
}
+// finalize
+int wis_db_final (void *k, void *data, va_list ap) {
+ struct WisData *p = (struct WisData *) data;
+ if (p) aFree(p);
+ return 0;
+}
+void inter_final() {
+ numdb_final(wis_db, wis_db_final);
+
+ inter_guild_sql_final();
+ inter_storage_sql_final();
+ inter_party_sql_final();
+ inter_pet_sql_final();
+
+ if (accreg_pt) aFree(accreg_pt);
+ return;
+}
+
int inter_mapif_init(int fd) {
inter_guild_mapif_init(fd);
@@ -293,13 +326,13 @@ int inter_mapif_init(int fd) {
//--------------------------------------------------------
// GM message sending
-int mapif_GMmessage(unsigned char *mes, int len) {
+int mapif_GMmessage(unsigned char *mes, int len, int sfd) {
unsigned char buf[len];
WBUFW(buf, 0) = 0x3800;
WBUFW(buf, 2) = len;
memcpy(WBUFP(buf, 4), mes, len-4);
- mapif_sendall(buf, len);
+ mapif_sendallwos(sfd, buf, len);
printf("\033[1;34m inter server: GM[len:%d] - '%s' \033[0m\n", len, mes);
return 0;
}
@@ -322,7 +355,7 @@ int mapif_wis_message(struct WisData *wd) {
int mapif_wis_end(struct WisData *wd,int flag)
{
unsigned char buf[27];
-
+
WBUFW(buf, 0)=0x3802;
memcpy(WBUFP(buf, 2),wd->src,24);
WBUFB(buf,26)=flag;
@@ -345,7 +378,7 @@ int mapif_account_reg_reply(int fd,int account_id)
{
struct accreg *reg=accreg_pt;
inter_accreg_fromsql(account_id,reg);
-
+
WFIFOW(fd,0)=0x3804;
WFIFOL(fd,4)=account_id;
if(reg->reg_num==0){
@@ -362,6 +395,27 @@ int mapif_account_reg_reply(int fd,int account_id)
return 0;
}
+int mapif_send_gmaccounts()
+{
+ int i, len = 4;
+ unsigned char buf[32000];
+
+ // forward the gm accounts to the map server
+ len = 4;
+ WBUFW(buf,0) = 0x2b15;
+
+ for(i = 0; i < GM_num; i++) {
+ WBUFL(buf, len) = gm_account[i].account_id;
+ WBUFB(buf, len+4) = (unsigned char)gm_account[i].level;
+ len += 5;
+ }
+ WBUFW(buf, 2) = len;
+ mapif_sendall(buf, len);
+
+ return 0;
+}
+
+
//--------------------------------------------------------
// Existence check of WISP data
@@ -384,12 +438,12 @@ int check_ttl_wisdata() {
wis_delnum = 0;
numdb_foreach(wis_db, check_ttl_wisdata_sub, tick);
for(i = 0; i < wis_delnum; i++) {
- struct WisData *wd = numdb_search(wis_db, wis_dellist[i]);
+ struct WisData *wd = (struct WisData*)numdb_search(wis_db, wis_dellist[i]);
printf("inter: wis data id=%d time out : from %s to %s\n", wd->id, wd->src, wd->dst);
// removed. not send information after a timeout. Just no answer for the player
//mapif_wis_end(wd, 1); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
numdb_erase(wis_db, wd->id);
- free(wd);
+ aFree(wd);
}
} while(wis_delnum >= WISDELLIST_MAX);
@@ -401,7 +455,7 @@ int check_ttl_wisdata() {
// GM message sending
int mapif_parse_GMmessage(int fd)
{
- mapif_GMmessage(RFIFOP(fd, 4), RFIFOW(fd, 2));
+ mapif_GMmessage(RFIFOP(fd, 4), RFIFOW(fd, 2), fd);
return 0;
}
@@ -410,6 +464,7 @@ int mapif_parse_GMmessage(int fd)
int mapif_parse_WisRequest(int fd) {
struct WisData* wd;
static int wisid = 0;
+ char t_name[32];
if (RFIFOW(fd,2)-52 >= sizeof(wd->msg)) {
printf("inter: Wis message size too long.\n");
@@ -418,7 +473,8 @@ int mapif_parse_WisRequest(int fd) {
printf("inter: Wis message doesn't exist.\n");
return 0;
}
- sprintf (tmp_sql, "SELECT `name` FROM `%s` WHERE `char_id`='%d'",char_db, (int) RFIFOP(fd,28));
+ sprintf (tmp_sql, "SELECT `name` FROM `%s` WHERE `name`='%s'",
+ char_db, jstrescapecpy(t_name, (char *)RFIFOP(fd,28)));
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
}
@@ -435,9 +491,9 @@ int mapif_parse_WisRequest(int fd) {
} else {
// to be sure of the correct name, rewrite it
memset(RFIFOP(fd,28), 0, 24);
- strncpy(RFIFOP(fd,28), sql_row[0], 24);
+ strncpy((char*)RFIFOP(fd,28), sql_row[0], 24);
// if source is destination, don't ask other servers.
- if (strcmp(RFIFOP(fd,4),RFIFOP(fd,28)) == 0) {
+ if (strcmp((char*)RFIFOP(fd,4),(char*)RFIFOP(fd,28)) == 0) {
unsigned char buf[27];
WBUFW(buf, 0) = 0x3802;
memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), 24);
@@ -461,7 +517,12 @@ int mapif_parse_WisRequest(int fd) {
mapif_wis_message(wd);
}
}
-
+
+ //Freeing ... O.o
+ if(sql_res){
+ mysql_free_result(sql_res);
+ }
+
return 0;
}
@@ -469,7 +530,7 @@ int mapif_parse_WisRequest(int fd) {
// Wisp/page transmission result
int mapif_parse_WisReply(int fd) {
int id = RFIFOL(fd,2), flag = RFIFOB(fd,6);
- struct WisData *wd = numdb_search(wis_db, id);
+ struct WisData *wd = (struct WisData*)numdb_search(wis_db, id);
if (wd == NULL)
return 0; // This wisp was probably suppress before, because it was timeout of because of target was found on another map-server
@@ -477,7 +538,7 @@ int mapif_parse_WisReply(int fd) {
if ((--wd->count) <= 0 || flag != 1) {
mapif_wis_end(wd, flag); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
numdb_erase(wis_db, id);
- free(wd);
+ aFree(wd);
}
return 0;
@@ -491,13 +552,13 @@ int mapif_parse_AccReg(int fd)
struct accreg *reg=accreg_pt;
int account_id = RFIFOL(fd,4);
memset(accreg_pt,0,sizeof(struct accreg));
-
+
for(j=0,p=8;j<ACCOUNT_REG_NUM && p<RFIFOW(fd,2);j++,p+=36){
memcpy(reg->reg[j].str,RFIFOP(fd,p),32);
reg->reg[j].value=RFIFOL(fd,p+32);
}
reg->reg_num=j;
-
+
inter_accreg_tosql(account_id,reg);
mapif_account_reg(fd,RFIFOP(fd,0)); // Send confirm message to map
return 0;
@@ -526,7 +587,7 @@ int inter_parse_frommap(int fd)
// ƒpƒPƒbƒg’·‚𒲂ׂé
if( (len=inter_check_length(fd,inter_recv_packet_length[cmd-0x3000]))==0 )
return 2;
-
+
switch(cmd){
case 0x3000: mapif_parse_GMmessage(fd); break;
case 0x3001: mapif_parse_WisRequest(fd); break;
@@ -556,9 +617,9 @@ int inter_check_length(int fd, int length)
return 0;
length = RFIFOW(fd, 2);
}
-
+
if(RFIFOREST(fd)<length) // packet not yet
return 0;
-
+
return length;
}
diff --git a/src/char_sql/inter.h b/src/char_sql/inter.h
index 398088504..9265a8d82 100644
--- a/src/char_sql/inter.h
+++ b/src/char_sql/inter.h
@@ -2,9 +2,10 @@
#define _INTER_H_
int inter_init(const char *file);
+void inter_final();
int inter_parse_frommap(int fd);
int inter_mapif_init(int fd);
-
+int mapif_send_gmaccounts();
int inter_check_length(int fd,int length);
@@ -24,6 +25,11 @@ extern MYSQL_RES* sql_res ;
extern MYSQL_ROW sql_row ;
extern int sql_cnt;
+extern MYSQL lmysql_handle;
+extern char tmp_lsql[65535];
+extern MYSQL_RES* lsql_res ;
+extern MYSQL_ROW lsql_row ;
+
extern int char_server_port;
extern char char_server_ip[32];
extern char char_server_id[32];
diff --git a/src/char_sql/itemdb.c b/src/char_sql/itemdb.c
index d045189a0..bc3e8603e 100644
--- a/src/char_sql/itemdb.c
+++ b/src/char_sql/itemdb.c
@@ -13,8 +13,6 @@
#include "memwatch.h"
#endif
-#define mysql_query(_x, _y) debug_mysql_query(__FILE__, __LINE__, _x, _y)
-
#define MAX_RANDITEM 2000
// ** ITEMDB_OVERRIDE_NAME_VERBOSE **
@@ -33,7 +31,7 @@ struct item_data* itemdb_search(int nameid)
{
struct item_data *id;
- id=numdb_search(item_db,nameid);
+ id = (struct item_data*)numdb_search(item_db,nameid);
if(id) return id;
CREATE(id, struct item_data, 1);
@@ -123,7 +121,7 @@ static int itemdb_readdb(void)
}
if(str[0]==NULL)
continue;
-
+
nameid=atoi(str[0]);
if(nameid<=0 || nameid>=20000)
continue;
@@ -174,7 +172,7 @@ static int itemdb_read_sqldb(void) // sql item_db read, shortened version of map
// Insert a new row into the item database
/*
- id = calloc(sizeof(struct item_data), 1);
+ id = aCalloc(sizeof(struct item_data), 1);
if (id == NULL) {
printf("out of memory : itemdb_read_sqldb\n");
@@ -187,7 +185,7 @@ static int itemdb_read_sqldb(void) // sql item_db read, shortened version of map
// ----------
*/
id=itemdb_search(nameid);
-
+
memcpy(id->name, sql_row[1], 24);
memcpy(id->jname, sql_row[2], 24);
@@ -214,12 +212,12 @@ static int itemdb_final(void *key,void *data,va_list ap)
{
struct item_data *id;
- id=data;
+ id = (struct item_data*)data;
if(id->use_script)
- free(id->use_script);
+ aFree(id->use_script);
if(id->equip_script)
- free(id->equip_script);
- free(id);
+ aFree(id->equip_script);
+ aFree(id);
return 0;
}
diff --git a/src/char_sql/itemdb.h b/src/char_sql/itemdb.h
index dea835e78..762873c8e 100644
--- a/src/char_sql/itemdb.h
+++ b/src/char_sql/itemdb.h
@@ -6,7 +6,7 @@ struct item_data {
char name[24],jname[24];
int value_buy,value_sell,value_notdc,value_notoc;
int type;
- int class;
+ int class_;
int sex;
int equip;
int weight;
diff --git a/src/char_sql/make.sh b/src/char_sql/make.sh
index a4ca8b5e4..6ee175f73 100644
--- a/src/char_sql/make.sh
+++ b/src/char_sql/make.sh
@@ -6,6 +6,5 @@
gcc -c int_pet.c -I/usr/local/include/mysql/
gcc -c int_storage.c -I/usr/local/include/mysql/
gcc -c inter.c -I/usr/local/include/mysql/
- gcc -c strlib.c
gcc -c itemdb.c -I../common/
- gcc -o ../char-server inter.o char.o int_pet.o int_storage.o int_guild.o int_party.o strlib.o itemdb.o ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o -L/usr/local/lib/mysql -lmysqlclient -lz
+ gcc -o ../char-server inter.o char.o int_pet.o int_storage.o int_guild.o int_party.o ../common/strlib.o itemdb.o ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o -L/usr/local/lib/mysql -lmysqlclient -lz
diff --git a/src/char_sql/strlib.h b/src/char_sql/strlib.h
deleted file mode 100644
index 6b6169083..000000000
--- a/src/char_sql/strlib.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _J_STR_LIB_H_
-#define _J_STR_LIB_H_
-#define J_MAX_MALLOC_SIZE 65535
-// String function library.
-// code by Jioh L. Jung (ziozzang@4wish.net)
-// This code is under license "BSD"
-unsigned char* jstrescape (unsigned char* pt);
-unsigned char* jstrescapecpy (unsigned char* pt,unsigned char* spt);
-int jmemescapecpy (unsigned char* pt,unsigned char* spt, int size);
-#endif
diff --git a/src/common/GNUmakefile b/src/common/GNUmakefile
deleted file mode 100644
index b15d4d481..000000000
--- a/src/common/GNUmakefile
+++ /dev/null
@@ -1,14 +0,0 @@
-txt sql all: core.o socket.o timer.o grfio.o db.o lock.o nullpo.o malloc.o showmsg.o
-
-core.o: core.c core.h showmsg.h
-socket.o: socket.c socket.h mmo.h showmsg.h
-timer.o: timer.c timer.h showmsg.h
-grfio.o: grfio.c grfio.h showmsg.h
-db.o: db.c db.h showmsg.h
-lock.o: lock.h showmsg.h
-nullpo.o: nullpo.c nullpo.h showmsg.h
-malloc.o: malloc.c malloc.h showmsg.h
-showmsg.o: showmsg.c showmsg.h
-
-clean:
- rm -f *.o
diff --git a/src/common/Makefile b/src/common/Makefile
index b15d4d481..7a00c5a3c 100644
--- a/src/common/Makefile
+++ b/src/common/Makefile
@@ -1,14 +1,23 @@
-txt sql all: core.o socket.o timer.o grfio.o db.o lock.o nullpo.o malloc.o showmsg.o
-
-core.o: core.c core.h showmsg.h
-socket.o: socket.c socket.h mmo.h showmsg.h
-timer.o: timer.c timer.h showmsg.h
-grfio.o: grfio.c grfio.h showmsg.h
-db.o: db.c db.h showmsg.h
-lock.o: lock.h showmsg.h
-nullpo.o: nullpo.c nullpo.h showmsg.h
-malloc.o: malloc.c malloc.h showmsg.h
-showmsg.o: showmsg.c showmsg.h
+txt sql all: obj common
+
+obj:
+ mkdir obj
+
+common: obj/core.o obj/socket.o obj/timer.o obj/grfio.o obj/db.o obj/lock.o obj/nullpo.o obj/malloc.o obj/showmsg.o obj/strlib.o obj/utils.o
+
+obj/%.o: %.c
+ $(COMPILE.c) $(OUTPUT_OPTION) $<
+
+obj/core.o: core.c core.h showmsg.h
+obj/socket.o: socket.c socket.h mmo.h showmsg.h dll.h
+obj/timer.o: timer.c timer.h showmsg.h
+obj/grfio.o: grfio.c grfio.h showmsg.h
+obj/db.o: db.c db.h showmsg.h
+obj/lock.o: lock.h showmsg.h
+obj/nullpo.o: nullpo.c nullpo.h showmsg.h
+obj/malloc.o: malloc.c malloc.h showmsg.h
+obj/showmsg.o: showmsg.c showmsg.h
+obj/strlib.o: strlib.c strlib.h utils.h
clean:
- rm -f *.o
+ rm -rf *.o obj
diff --git a/src/common/buffer.h b/src/common/buffer.h
new file mode 100644
index 000000000..ea94380ce
--- /dev/null
+++ b/src/common/buffer.h
@@ -0,0 +1,18 @@
+#ifndef _BUFFER_H_
+#define _BUFFER_H_
+
+// Full credit for this goes to Shinomori [Ajarn]
+
+#ifdef __GNUC__ // GCC has variable length arrays
+
+#define CREATE_BUFFER(name, type, size) type name[size]
+#define DELETE_BUFFER(name)
+
+#else // others don't, so we emulate them
+
+#define CREATE_BUFFER(name, type, size) type *name=(type*)aCalloc(size,sizeof(type))
+#define DELETE_BUFFER(name) aFree(name);name=NULL
+
+#endif
+
+#endif
diff --git a/src/common/core.c b/src/common/core.c
index 167b38efb..0a9e76120 100644
--- a/src/common/core.c
+++ b/src/common/core.c
@@ -8,17 +8,29 @@
#endif
#include <signal.h>
#include <string.h>
+#ifdef DUMPSTACK
+ #ifndef CYGWIN // HAVE_EXECINFO_H
+ #include <execinfo.h>
+ #endif
+#endif
#include "core.h"
-#include "socket.h"
-#include "timer.h"
-#include "version.h"
-#include "showmsg.h"
+#include "../common/mmo.h"
+#include "../common/malloc.h"
+#include "../common/socket.h"
+#include "../common/timer.h"
+#include "../common/version.h"
+#include "../common/showmsg.h"
#ifdef MEMWATCH
#include "memwatch.h"
#endif
+char *argp;
+int runflag = 1;
+char SERVER_TYPE = SERVER_NONE;
+unsigned long ticks = 0; // by MC Cameri
+char pid_file[256];
static void (*term_func)(void)=NULL;
/*======================================
@@ -30,14 +42,54 @@ void set_termfunc(void (*termfunc)(void))
term_func = termfunc;
}
+// Added by Gabuzomeu
+//
+// This is an implementation of signal() using sigaction() for portability.
+// (sigaction() is POSIX; signal() is not.) Taken from Stevens' _Advanced
+// Programming in the UNIX Environment_.
+//
+#ifndef SIGPIPE
+#define SIGPIPE SIGINT
+#endif
+
+#ifndef POSIX
+#define compat_signal(signo, func) signal(signo, func)
+#else
+sigfunc *compat_signal(int signo, sigfunc *func)
+{
+ struct sigaction sact, oact;
+
+ sact.sa_handler = func;
+ sigemptyset(&sact.sa_mask);
+ sact.sa_flags = 0;
+#ifdef SA_INTERRUPT
+ sact.sa_flags |= SA_INTERRUPT; /* SunOS */
+#endif
+
+ if (sigaction(signo, &sact, &oact) < 0)
+ return (SIG_ERR);
+
+ return (oact.sa_handler);
+}
+#endif
+
/*======================================
* CORE : Signal Sub Function
*--------------------------------------
*/
-
+// for handling certain signals ourselves, like SIGPIPE
+static void sig_ignore(int sn) {
+ printf ("Broken pipe found... closing socket\n"); // set to eof in socket.c
+ return; // does nothing here
+}
static void sig_proc(int sn)
{
int i;
+ static int is_called = 0;
+
+ if(is_called++)
+ return;
+
switch(sn){
case SIGINT:
case SIGTERM:
@@ -53,6 +105,66 @@ static void sig_proc(int sn)
}
}
+/*=========================================
+ * Dumps the stack using glibc's backtrace
+ *-----------------------------------------
+ */
+#ifndef DUMPSTACK
+ #define sig_dump SIG_DFL
+#else
+ #ifdef CYGWIN
+ #define FOPEN_ freopen
+ extern void cygwin_stackdump();
+ #else
+ #define FOPEN_(fn,m,s) fopen(fn,m)
+ #endif
+extern const char *strsignal(int);
+void sig_dump(int sn)
+{
+ FILE *fp;
+ char file[256];
+ int no = 0;
+
+ #ifndef CYGWIN
+ void* array[20];
+ char **stack;
+ size_t size;
+ #endif
+
+ // search for a usable filename
+ do {
+ sprintf (file, "log/%s%04d.stackdump", argp, ++no);
+ } while((fp = fopen(file,"r")) && (fclose(fp), no < 9999));
+ // dump the trace into the file
+
+ if ((fp = FOPEN_(file, "w", stderr)) != NULL) {
+ printf ("Dumping stack... ");
+ fprintf(fp, "Exception: %s \n", strsignal(sn));
+ fflush (fp);
+
+ #ifdef CYGWIN
+ cygwin_stackdump ();
+ #else
+ fprintf(fp, "Stack trace:\n");
+ size = backtrace (array, 20);
+ stack = backtrace_symbols (array, size);
+ for (no = 0; no < size; no++) {
+ fprintf(fp, "%s\n", stack[no]);
+ }
+ fprintf(fp,"End of stack trace\n");
+ aFree(stack);
+ #endif
+
+ printf ("Done.\n");
+ fflush(stdout);
+ fclose(fp);
+ }
+ // Pass the signal to the system's default handler
+ compat_signal(sn, SIG_DFL);
+ raise(sn);
+}
+#endif
+
int get_svn_revision(char *svnentry) { // Warning: minor syntax checking
char line[1024];
int rev = 0;
@@ -60,12 +172,13 @@ int get_svn_revision(char *svnentry) { // Warning: minor syntax checking
if ((fp = fopen(svnentry, "r")) == NULL) {
return 0;
} else {
- while (fgets(line,1023,fp)) if (strstr(line,"revision=")) break;
+ while (fgets(line,1023,fp))
+ if (strstr(line,"revision=")) break;
fclose(fp);
- if (sscanf(line," %*[^\"]\"%d%*[^\n]",&rev)==1)
- return rev;
+ if (sscanf(line," %*[^\"]\"%d%*[^\n]",&rev) == 1)
+ return rev;
else
- return 0;
+ return 0;
}
// return 0;
}
@@ -87,7 +200,7 @@ static void display_title(void)
// \033[1m : use bold for font
printf("\033[2J"); // clear screen and go up/left (0, 0 position in text)
printf("\033[37;44m (=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)\033[K\033[0m\n"); // white writing (37) on blue background (44), \033[K clean until end of file
- printf("\033[0;44m (\033[1;33m (c)2004 eAthena Development Team presents \033[0;44m)\033[K\033[0m\n"); // yellow writing (33)
+ printf("\033[0;44m (\033[1;33m (c)2005 eAthena Development Team presents \033[0;44m)\033[K\033[0m\n"); // yellow writing (33)
printf("\033[0;44m (\033[1m ______ __ __ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
printf("\033[0;44m (\033[1m /\\ _ \\/\\ \\__/\\ \\ v%2d.%02d.%02d \033[0;44m)\033[K\033[0m\n", ATHENA_MAJOR_VERSION, ATHENA_MINOR_VERSION, ATHENA_REVISION); // 1: bold char, 0: normal char
printf("\033[0;44m (\033[1m __\\ \\ \\_\\ \\ \\ ,_\\ \\ \\___ __ ___ __ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
@@ -100,80 +213,115 @@ static void display_title(void)
printf("\033[0;44m (\033[1m ( e | n | g | l | i | s | h ) ( A | t | h | e | n | a ) \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
printf("\033[0;44m (\033[1m \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
printf("\033[0;44m (\033[1m \033[0;44m)\033[K\033[0m\n"); // yellow writing (33)
- printf("\033[0;44m (\033[1;33m Advanced Fusion Maps (c) 2003-2004 The Fusion Project \033[0;44m)\033[K\033[0m\n"); // yellow writing (33)
+ printf("\033[0;44m (\033[1;33m Advanced Fusion Maps (c) 2003-2005 The Fusion Project \033[0;44m)\033[K\033[0m\n"); // yellow writing (33)
printf("\033[37;44m (=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)\033[K\033[0m\n\n"); // reset color
if ((revision = get_svn_revision(".svn\\entries"))>0) {
- snprintf(tmp_output,sizeof(tmp_output),"SVN Revision: %d.\n",revision);
+ snprintf(tmp_output,sizeof(tmp_output),"SVN Revision: '"CL_WHITE"%d"CL_RESET"'.\n",revision);
ShowInfo(tmp_output);
}
}
-// Added by Gabuzomeu
-//
-// This is an implementation of signal() using sigaction() for portability.
-// (sigaction() is POSIX; signal() is not.) Taken from Stevens' _Advanced
-// Programming in the UNIX Environment_.
-//
-#ifndef SIGPIPE
-#define SIGPIPE SIGINT
-#endif
+/*======================================
+ * CORE : MAINROUTINE
+ *--------------------------------------
+ */
-#ifndef POSIX
-#define compat_signal(signo, func) signal(signo, func)
-#else
-sigfunc *compat_signal(int signo, sigfunc *func)
-{
- struct sigaction sact, oact;
+void pid_delete(void) {
+ unlink(pid_file);
+}
- sact.sa_handler = func;
- sigemptyset(&sact.sa_mask);
- sact.sa_flags = 0;
-#ifdef SA_INTERRUPT
- sact.sa_flags |= SA_INTERRUPT; /* SunOS */
+void pid_create(const char* file) {
+ FILE *fp;
+ int len = strlen(file);
+ strcpy(pid_file,file);
+ if(len > 4 && pid_file[len - 4] == '.') {
+ pid_file[len - 4] = 0;
+ }
+ strcat(pid_file,".pid");
+ fp = fopen(pid_file,"w");
+ if(fp) {
+#ifdef _WIN32
+ fprintf(fp,"%d",GetCurrentProcessId());
+#else
+ fprintf(fp,"%d",getpid());
#endif
+ fclose(fp);
+ atexit(pid_delete);
+ }
+}
- if (sigaction(signo, &sact, &oact) < 0)
- return (SIG_ERR);
+#define LOG_UPTIME 0
+void log_uptime(void)
+{
+#if LOG_UPTIME
+ time_t curtime;
+ char curtime2[24];
+ FILE *fp;
+ long seconds = 0, day = 24*60*60, hour = 60*60,
+ minute = 60, days = 0, hours = 0, minutes = 0;
- return (oact.sa_handler);
-}
-#endif
+ fp = fopen("log/uptime.log","a");
+ if (fp) {
+ time(&curtime);
+ strftime(curtime2, 24, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+ seconds = (gettick()-ticks)/CLOCKS_PER_SEC;
+ days = seconds/day;
+ seconds -= (seconds/day>0)?(seconds/day)*day:0;
+ hours = seconds/hour;
+ seconds -= (seconds/hour>0)?(seconds/hour)*hour:0;
+ minutes = seconds/minute;
+ seconds -= (seconds/minute>0)?(seconds/minute)*minute:0;
-/*======================================
- * CORE : MAINROUTINE
- *--------------------------------------
- */
+ fprintf(fp, "%s: %s uptime - %ld days, %ld hours, %ld minutes, %ld seconds.\n",
+ curtime2, argp, days, hours, minutes, seconds);
+ fclose(fp);
+ }
-int runflag = 1;
+ return;
+#endif
+}
int main(int argc,char **argv)
{
int next;
+ if ((argp = strstr(argv[0], "./")) != NULL)
+ argp+=2;
+ else argp = argv[0];
+
+ display_title();
+
+ do_init_memmgr(argp); // ˆê”Ôʼn‚ÉŽÀs‚·‚é•K—v‚ª‚ ‚é
+ atexit(log_uptime);
+ pid_create(argp);
Net_Init();
do_socket();
- compat_signal(SIGPIPE,SIG_IGN);
+ compat_signal(SIGPIPE, sig_ignore);
compat_signal(SIGTERM,sig_proc);
compat_signal(SIGINT,sig_proc);
-
+
// Signal to create coredumps by system when necessary (crash)
- compat_signal(SIGSEGV, SIG_DFL);
-#ifndef _WIN32
- compat_signal(SIGBUS, SIG_DFL);
- compat_signal(SIGTRAP, SIG_DFL);
-#endif
- compat_signal(SIGILL, SIG_DFL);
+ compat_signal(SIGSEGV, sig_dump);
+ compat_signal(SIGFPE, sig_dump);
+ compat_signal(SIGILL, sig_dump);
+ #ifndef _WIN32
+ compat_signal(SIGBUS, sig_dump);
+ compat_signal(SIGTRAP, SIG_DFL);
+ #endif
- display_title();
+ tick_ = time(0);
+ ticks = gettick();
do_init(argc,argv);
+
while(runflag){
next=do_timer(gettick_nocache());
do_sendrecv(next);
do_parsepacket();
}
+
return 0;
}
diff --git a/src/common/core.h b/src/common/core.h
index bc2be02c2..e9b5c8227 100644
--- a/src/common/core.h
+++ b/src/common/core.h
@@ -3,10 +3,19 @@
#ifndef _CORE_H_
#define _CORE_H_
+extern char *argp;
extern int runflag;
+extern unsigned long ticks;
+extern char SERVER_TYPE;
-int do_init(int,char**);
+enum {
+ SERVER_NONE,
+ SERVER_LOGIN,
+ SERVER_CHAR,
+ SERVER_MAP,
+};
+int do_init(int,char**);
void set_termfunc(void (*termfunc)(void));
#endif // _CORE_H_
diff --git a/src/common/db.c b/src/common/db.c
index 58f0ea4f7..377128e8f 100644
--- a/src/common/db.c
+++ b/src/common/db.c
@@ -1,18 +1,26 @@
// $Id: db.c,v 1.2 2004/09/23 14:43:06 MouseJstr Exp $
-// #define MALLOC_DBN
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "db.h"
#include "mmo.h"
#include "utils.h"
+#include "malloc.h"
#ifdef MEMWATCH
#include "memwatch.h"
#endif
-#define ROOT_SIZE 4096
+//#define MALLOC_DBN
+
+// Backup cleaning routine in case the core doesn't do so properly,
+// only enabled if malloc_dbn is not defined.
+// As a temporary solution the root of the problem should still be found and fixed
+struct dbn *head;
+struct dbn *tail;
+
#ifdef MALLOC_DBN
+#define ROOT_SIZE 4096
static struct dbn *dbn_root[512], *dbn_free;
static int dbn_root_rest=0,dbn_root_num=0;
@@ -39,20 +47,50 @@ static void free_dbn(struct dbn* add_dbn)
add_dbn->parent = dbn_free;
dbn_free = add_dbn;
}
+
+void exit_dbn(void)
+{
+ int i;
+
+ for (i=0;i<dbn_root_num;i++)
+ if (dbn_root[i])
+ aFree(dbn_root[i]);
+
+ dbn_root_rest=0;
+ dbn_root_num=0;
+
+ return;
+}
+#else
+void exit_dbn(void)
+{
+ int i = 0;
+ struct dbn *p = head, *p2;
+ while (p) {
+ p2 = p->next;
+ aFree(p);
+ p = p2;
+ i++;
+ }
+ //printf ("freed %d stray dbn\n", i);
+ return;
+}
#endif
+// maybe change the void* to const char* ???
static int strdb_cmp(struct dbt* table,void* a,void* b)
{
if(table->maxlen)
- return strncmp(a,b,table->maxlen);
- return strcmp(a,b);
+ return strncmp((const char*)a,(const char*)b,table->maxlen);
+ return strcmp((const char*)a,(const char*)b);
}
+// maybe change the void* to unsigned char* ???
static unsigned int strdb_hash(struct dbt* table,void* a)
{
int i;
unsigned int h;
- unsigned char *p=a;
+ unsigned char *p = (unsigned char*)a;
i=table->maxlen;
if(i==0) i=0x7fffffff;
@@ -62,7 +100,7 @@ static unsigned int strdb_hash(struct dbt* table,void* a)
return h;
}
-struct dbt* strdb_init(int maxlen)
+struct dbt* strdb_init_(int maxlen,const char *file,int line)
{
int i;
struct dbt* table;
@@ -74,6 +112,9 @@ struct dbt* strdb_init(int maxlen)
table->maxlen=maxlen;
for(i=0;i<HASH_SIZE;i++)
table->ht[i]=NULL;
+ table->alloc_file = file;
+ table->alloc_line = line;
+ table->item_count = 0;
return table;
}
@@ -95,7 +136,7 @@ static unsigned int numdb_hash(struct dbt* table,void* a)
return (unsigned int)a;
}
-struct dbt* numdb_init(void)
+struct dbt* numdb_init_(const char *file,int line)
{
int i;
struct dbt* table;
@@ -107,6 +148,9 @@ struct dbt* numdb_init(void)
table->maxlen=sizeof(int);
for(i=0;i<HASH_SIZE;i++)
table->ht[i]=NULL;
+ table->alloc_file = file;
+ table->alloc_line = line;
+ table->item_count = 0;
return table;
}
@@ -130,14 +174,14 @@ void * db_search2(struct dbt *table, const char *key)
{
int i,sp;
struct dbn *p,*pn,*stack[64];
- int slen = strlen(key);
+ int slen = strlen(key);
for(i=0;i<HASH_SIZE;i++){
if((p=table->ht[i])==NULL)
continue;
sp=0;
while(1){
- if (strnicmp(key, p->key, slen) == 0)
+ if (strnicmp(key, (const char*)p->key, slen) == 0)
return p->data;
if((pn=p->left)!=NULL){
if(p->right){
@@ -345,6 +389,29 @@ static void db_rebalance_erase(struct dbn *z,struct dbn **root)
}
}
+void db_free_lock(struct dbt *table) {
+ table->free_lock++;
+}
+
+void db_free_unlock(struct dbt *table) {
+ if(--table->free_lock == 0) {
+ int i;
+ for(i = 0; i < table->free_count ; i++) {
+ db_rebalance_erase(table->free_list[i].z,table->free_list[i].root);
+ if(table->cmp == strdb_cmp) {
+ aFree(table->free_list[i].z->key);
+ }
+#ifdef MALLOC_DBN
+ free_dbn(table->free_list[i].z);
+#else
+ aFree(table->free_list[i].z);
+#endif
+ table->item_count--;
+ }
+ table->free_count = 0;
+ }
+}
+
struct dbn* db_insert(struct dbt *table,void* key,void* data)
{
struct dbn *p,*priv;
@@ -354,10 +421,33 @@ struct dbn* db_insert(struct dbt *table,void* key,void* data)
for(c=0,priv=NULL ,p = table->ht[hash];p;){
c=table->cmp(table,key,p->key);
if(c==0){ // replace
- if (table->release)
- table->release(p, 3);
+ if (table->release)
+ table->release(p, 3);
+ if(p->deleted) {
+ // 휂³‚ꂽƒf[ƒ^‚Ȃ̂ÅAfree_list ã‚Ì휗\’è‚ðÁ‚·
+ int i;
+ for(i = 0; i < table->free_count ; i++) {
+ if(table->free_list[i].z == p) {
+ memmove(
+ &table->free_list[i],
+ &table->free_list[i+1],
+ sizeof(struct db_free)*(table->free_count - i - 1)
+ );
+ break;
+ }
+ }
+ if(i == table->free_count || table->free_count <= 0) {
+ printf("db_insert: cannnot find deleted db node.\n");
+ } else {
+ table->free_count--;
+ if(table->cmp == strdb_cmp) {
+ aFree(p->key);
+ }
+ }
+ }
p->data=data;
p->key=key;
+ p->deleted = 0;
return p;
}
priv=p;
@@ -382,6 +472,17 @@ struct dbn* db_insert(struct dbt *table,void* key,void* data)
p->key = key;
p->data = data;
p->color = RED;
+ p->deleted = 0;
+ p->prev = NULL;
+ p->next = NULL;
+ if (head == NULL)
+ head = tail = p;
+ else {
+ p->prev = tail;
+ tail->next = p;
+ tail = p;
+ }
+
if(c==0){ // hash entry is empty
table->ht[hash] = p;
p->color = BLACK;
@@ -397,6 +498,8 @@ struct dbn* db_insert(struct dbt *table,void* key,void* data)
db_rebalance(p,&table->ht[hash]);
}
}
+ table->item_count++;
+
return p;
}
@@ -419,29 +522,69 @@ void* db_erase(struct dbt *table,void* key)
if(!p)
return NULL;
data=p->data;
- db_rebalance_erase(p,&table->ht[hash]);
-#ifdef MALLOC_DBN
- free_dbn(p);
-#else
- free(p);
-#endif
+ if(table->free_lock) {
+ if(table->free_count == table->free_max) {
+ table->free_max += 32;
+ table->free_list = (struct db_free*)realloc(table->free_list,sizeof(struct db_free) * table->free_max);
+ }
+ table->free_list[table->free_count].z = p;
+ table->free_list[table->free_count].root = &table->ht[hash];
+ table->free_count++;
+ p->deleted = 1;
+ p->data = NULL;
+ if(table->cmp == strdb_cmp) {
+ if(table->maxlen) {
+ char *key = (char*)malloc(table->maxlen);
+ memcpy(key,p->key,table->maxlen);
+ p->key = key;
+ } else {
+ p->key = strdup((const char*)p->key);
+ }
+ }
+ } else {
+ db_rebalance_erase(p,&table->ht[hash]);
+ if (p->prev)
+ p->prev->next = p->next;
+ else
+ head = p->next;
+ if (p->next)
+ p->next->prev = p->prev;
+ else
+ tail = p->prev;
+
+ #ifdef MALLOC_DBN
+ free_dbn(p);
+ #else
+ aFree(p);
+ #endif
+ table->item_count--;
+ }
return data;
}
void db_foreach(struct dbt *table,int (*func)(void*,void*,va_list),...)
{
int i,sp;
+ int count = table->item_count;
// red-black tree‚Ȃ̂Å64ŒÂstack‚ª‚ ‚ê‚Î2^32ŒÂƒm[ƒh‚܂őåä•v
struct dbn *p,*pn,*stack[64];
va_list ap;
va_start(ap,func);
+ db_free_lock(table);
for(i=0;i<HASH_SIZE;i++){
if((p=table->ht[i])==NULL)
continue;
sp=0;
while(1){
- func(p->key,p->data,ap);
+ //reverted it back. sorry that brought thios bug from Freya [Lupus]
+ //if (!p->data) {
+ // printf("Warning: no data for key %d in db_foreach (db.c) !\n",(int)p->key);
+ //} else {
+ if(!p->deleted)
+ func(p->key, p->data, ap);
+ count--;
+ //}
if((pn=p->left)!=NULL){
if(p->right){
stack[sp++]=p->right;
@@ -458,6 +601,13 @@ void db_foreach(struct dbt *table,int (*func)(void*,void*,va_list),...)
}
}
}
+ db_free_unlock(table);
+ if(count) {
+ printf(
+ "db_foreach : data lost %d item(s) allocated from %s line %d\n",
+ count,table->alloc_file,table->alloc_line
+ );
+ }
va_end(ap);
}
@@ -468,12 +618,13 @@ void db_final(struct dbt *table,int (*func)(void*,void*,va_list),...)
va_list ap;
va_start(ap,func);
+ db_free_lock(table);
for(i=0;i<HASH_SIZE;i++){
if((p=table->ht[i])==NULL)
continue;
sp=0;
while(1){
- if(func)
+ if(func && !p->deleted)
func(p->key,p->data,ap);
if((pn=p->left)!=NULL){
if(p->right){
@@ -488,14 +639,24 @@ void db_final(struct dbt *table,int (*func)(void*,void*,va_list),...)
pn=stack[--sp];
}
}
+ if (p->prev)
+ p->prev->next = p->next;
+ else
+ head = p->next;
+ if (p->next)
+ p->next->prev = p->prev;
+ else
+ tail = p->prev;
#ifdef MALLOC_DBN
free_dbn(p);
#else
- free(p);
+ aFree(p);
#endif
p=pn;
}
}
- free(table);
+ db_free_unlock(table);
+ aFree(table->free_list);
+ aFree(table);
va_end(ap);
}
diff --git a/src/common/db.h b/src/common/db.h
index ea9aceab0..6980099cf 100644
--- a/src/common/db.h
+++ b/src/common/db.h
@@ -13,6 +13,14 @@ struct dbn {
int color;
void *key;
void *data;
+ int deleted; // íœÏ‚݃tƒ‰ƒO(db_foreach)
+ struct dbn *next;
+ struct dbn *prev;
+};
+
+struct db_free {
+ struct dbn *z;
+ struct dbn **root;
};
struct dbt {
@@ -22,6 +30,15 @@ struct dbt {
void (*release)(struct dbn*,int which);
int maxlen;
struct dbn *ht[HASH_SIZE];
+ int item_count; // vf?
+ const char* alloc_file; // DB?t@C
+ int alloc_line; // DB?s
+ // db_foreach “à•”‚Ådb_erase ‚³‚ê‚é‘Îô‚Æ‚µ‚ÄA
+ // db_foreach ‚ªI‚í‚é‚܂ŃƒbƒN‚·‚邱‚Ƃɂ·‚é
+ struct db_free *free_list;
+ int free_count;
+ int free_max;
+ int free_lock;
};
#define strdb_search(t,k) db_search((t),(void*)(k))
@@ -34,14 +51,18 @@ struct dbt {
#define numdb_erase(t,k) db_erase ((t),(void*)(k))
#define numdb_foreach db_foreach
#define numdb_final db_final
+#define strdb_init(a) strdb_init_(a,__FILE__,__LINE__)
+#define numdb_init() numdb_init_(__FILE__,__LINE__)
+
+struct dbt* strdb_init_(int maxlen,const char *file,int line);
+struct dbt* numdb_init_(const char *file,int line);
-struct dbt* strdb_init(int maxlen);
-struct dbt* numdb_init(void);
void* db_search(struct dbt *table,void* key);
void* db_search2(struct dbt *table, const char *key); // [MouseJstr]
struct dbn* db_insert(struct dbt *table,void* key,void* data);
void* db_erase(struct dbt *table,void* key);
void db_foreach(struct dbt*,int(*)(void*,void*,va_list),...);
void db_final(struct dbt*,int(*)(void*,void*,va_list),...);
+void exit_dbn(void);
#endif
diff --git a/src/common/dll.h b/src/common/dll.h
new file mode 100644
index 000000000..50854da4d
--- /dev/null
+++ b/src/common/dll.h
@@ -0,0 +1,25 @@
+
+#ifndef _DLL_H_
+#define _DLL_H_
+
+#ifdef _WIN32
+
+ #include <windows.h>
+ #define DLL_OPEN(x) LoadLibrary(x)
+ #define DLL_SYM(x,y,z) (FARPROC)(x) = GetProcAddress(y,z)
+ #define DLL_CLOSE(x) FreeLibrary(x)
+ #define DLL HINSTANCE
+
+#else
+
+ #include <dlfcn.h>
+ #define DLL_OPEN(x) dlopen(x,RTLD_NOW)
+ #define DLL_SYM(x,y,z) (x) = (void *)dlsym(y,z)
+ #define DLL_CLOSE(x) dlclose(x)
+ #define DLL void *
+
+#endif
+
+#endif // _DLL_H_
+
+
diff --git a/src/common/grfio.c b/src/common/grfio.c
index ff01b6e76..1a3829bf7 100644
--- a/src/common/grfio.c
+++ b/src/common/grfio.c
@@ -25,11 +25,50 @@
#include <ctype.h>
#include <sys/stat.h>
-#include <zlib.h>
-
-#include "utils.h"
#include "grfio.h"
-#include "mmo.h"
+#include "../common/utils.h"
+#include "../common/mmo.h"
+#include "../common/showmsg.h"
+#include "../common/malloc.h"
+
+#ifdef _WIN32
+ #ifdef LOCALZLIB
+ #include "zlib.h"
+ #define zlib_inflateInit inflateInit
+ #define zlib_inflate inflate
+ #define zlib_inflateEnd inflateEnd
+ #define zlib_deflateInit deflateInit
+ #define zlib_deflate deflate
+ #define zlib_deflateEnd deflateEnd
+ #else
+ #include "../lib/zlib_win32.h"
+ #include "../common/dll.h"
+ DLL zlib_dll;
+ #define zlib_inflateInit(strm) zlib_inflateInit_((strm),ZLIB_VERSION, sizeof(z_stream))
+ #define zlib_deflateInit(strm, level) zlib_deflateInit_((strm),(level),ZLIB_VERSION,sizeof(z_stream))
+
+ int (WINAPI* zlib_inflateInit_) (z_streamp strm, const char *version, int stream_size);
+ int (WINAPI* zlib_inflate) (z_streamp strm, int flush);
+ int (WINAPI* zlib_inflateEnd) (z_streamp strm);
+
+ int (WINAPI* zlib_deflateInit_) (z_streamp strm, int level, const char *version, int stream_size);
+ int (WINAPI* zlib_deflate) (z_streamp strm, int flush);
+ int (WINAPI* zlib_deflateEnd) (z_streamp strm);
+ #endif
+#else
+ #ifdef LOCALZLIB
+ #include "zlib/zlib.h"
+ #else
+ #include <zlib.h>
+ #endif
+
+ #define zlib_inflateInit inflateInit
+ #define zlib_inflate inflate
+ #define zlib_inflateEnd inflateEnd
+ #define zlib_deflateInit deflateInit
+ #define zlib_deflate deflate
+ #define zlib_deflateEnd deflateEnd
+#endif
#ifdef MEMWATCH
#include "memwatch.h"
@@ -72,7 +111,7 @@ typedef struct {
//Since char defines *FILELIST.gentry, the maximum which can be added by grfio_add becomes by 127 pieces.
#define GENTRY_LIMIT 127
-#define FILELIST_LIMIT 32768 // temporary maximum, and a theory top maximum are 2G.
+#define FILELIST_LIMIT 65536 // temporary maximum, and a theory top maximum are 2G.
static FILELIST *filelist;
static int filelist_entrys;
@@ -139,7 +178,11 @@ static unsigned char NibbleData[4][64]={
*/
static unsigned int getlong(unsigned char *p)
{
- return *p+p[1]*256+(p[2]+p[3]*256)*65536;
+// return *p+p[1]*256+(p[2]+p[3]*256)*65536;
+ return p[0]
+ | p[1] << 0x08
+ | p[2] << 0x10
+ | p[3] << 0x18; // Shinomori
}
/*==========================================
@@ -157,15 +200,17 @@ static void BitConvert(BYTE *Src,char *BitSwapTable)
{
int lop,prm;
BYTE tmp[8];
- *(DWORD*)tmp=*(DWORD*)(tmp+4)=0;
+// *(DWORD*)tmp=*(DWORD*)(tmp+4)=0;
+ memset(tmp,0,8);
for(lop=0;lop!=64;lop++) {
prm = BitSwapTable[lop]-1;
if (Src[(prm >> 3) & 7] & BitMaskTable[prm & 7]) {
tmp[(lop >> 3) & 7] |= BitMaskTable[lop & 7];
}
}
- *(DWORD*)Src = *(DWORD*)tmp;
- *(DWORD*)(Src+4) = *(DWORD*)(tmp+4);
+// *(DWORD*)Src = *(DWORD*)tmp;
+// *(DWORD*)(Src+4) = *(DWORD*)(tmp+4);
+ memcpy(Src,tmp,8);
}
static void BitConvert4(BYTE *Src)
@@ -193,7 +238,11 @@ static void BitConvert4(BYTE *Src)
tmp[(lop >> 3) + 4] |= BitMaskTable[lop & 7];
}
}
- *(DWORD*)Src ^= *(DWORD*)(tmp+4);
+// *(DWORD*)Src ^= *(DWORD*)(tmp+4);
+ Src[0] ^= tmp[4];
+ Src[1] ^= tmp[5];
+ Src[2] ^= tmp[6];
+ Src[3] ^= tmp[7];
}
static void decode_des_etc(BYTE *buf,int len,int type,int cycle)
@@ -248,7 +297,7 @@ static void decode_des_etc(BYTE *buf,int len,int type,int cycle)
* Grf data decode sub : zip
*------------------------------------------
*/
-static int decode_zip(Bytef* dest, uLongf* destLen, const Bytef* source, uLong sourceLen)
+int decode_zip(unsigned char *dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen)
{
z_stream stream;
int err;
@@ -258,26 +307,57 @@ static int decode_zip(Bytef* dest, uLongf* destLen, const Bytef* source, uLong s
/* Check for source > 64K on 16-bit machine: */
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
- stream.next_out = dest;
+ stream.next_out = (Bytef*) dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+
+ err = zlib_inflateInit(&stream);
+ if (err != Z_OK) return err;
+
+ err = zlib_inflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ zlib_inflateEnd(&stream);
+ return err == Z_OK ? Z_BUF_ERROR : err;
+ }
+ *destLen = stream.total_out;
+
+ err = zlib_inflateEnd(&stream);
+ return err;
+}
+
+int encode_zip(unsigned char *dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen) {
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef*)source;
+ stream.avail_in = (uInt)sourceLen;
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+ stream.next_out = (Bytef*) dest;
stream.avail_out = (uInt)*destLen;
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
- err = inflateInit(&stream);
+ err = zlib_deflateInit(&stream,Z_DEFAULT_COMPRESSION);
if (err != Z_OK) return err;
- err = inflate(&stream, Z_FINISH);
+ err = zlib_deflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) {
- inflateEnd(&stream);
+ zlib_inflateEnd(&stream);
return err == Z_OK ? Z_BUF_ERROR : err;
}
*destLen = stream.total_out;
- err = inflateEnd(&stream);
+ err = zlib_deflateEnd(&stream);
return err;
}
+
/***********************************************************
*** File List Sobroutines ***
***********************************************************/
@@ -315,7 +395,7 @@ FILELIST *filelist_find(char *fname)
{
int hash;
- for(hash=filelist_hash[filehash(fname)];hash>=0;hash=filelist[hash].next) {
+ for(hash=filelist_hash[filehash((unsigned char *) fname)];hash>=0;hash=filelist[hash].next) {
if(strcmpi(filelist[hash].fn,fname)==0)
break;
}
@@ -339,7 +419,7 @@ static FILELIST* filelist_add(FILELIST *entry)
}
if (filelist_entrys>=filelist_maxentry) {
- FILELIST *new_filelist = (FILELIST*)realloc(
+ FILELIST *new_filelist = (FILELIST*)aRealloc(
(void*)filelist, (filelist_maxentry+FILELIST_ADDS)*sizeof(FILELIST) );
if (new_filelist != NULL) {
filelist = new_filelist;
@@ -354,7 +434,7 @@ static FILELIST* filelist_add(FILELIST *entry)
memcpy( &filelist[filelist_entrys], entry, sizeof(FILELIST) );
- hash = filehash(entry->fn);
+ hash = filehash((unsigned char *) entry->fn);
filelist[filelist_entrys].next = filelist_hash[hash];
filelist_hash[hash] = filelist_entrys;
@@ -384,7 +464,7 @@ static void filelist_adjust(void)
{
if (filelist!=NULL) {
if (filelist_maxentry>filelist_entrys) {
- FILELIST *new_filelist = (FILELIST*)realloc(
+ FILELIST *new_filelist = (FILELIST*)aRealloc(
(void*)filelist,filelist_entrys*sizeof(FILELIST) );
if (new_filelist != NULL) {
filelist = new_filelist;
@@ -443,17 +523,17 @@ int grfio_size(char *fname)
entry = filelist_find(fname);
if (entry==NULL || entry->gentry<0) { // LocalFileCheck
- char lfname[256],rname[256],*p;
+ char lfname[256],*rname,*p;
FILELIST lentry;
struct stat st;
-
- if(strcmp(data_dir, "") != 0) {
+
+ if(strcmp(data_dir, "") != 0 && (rname=grfio_resnametable(fname,lfname))!=NULL) {
//printf("%s\t",fname);
- sprintf(rname,"%s",grfio_resnametable(fname,lfname));
+ //sprintf(rname,"%s",grfio_resnametable(fname,lfname));
//printf("%s\n",rname);
sprintf(lfname,"%s%s",data_dir,rname);
//printf("%s\n",lfname);
- }
+ }
for(p=&lfname[0];*p!=0;p++) if (*p=='\\') *p = '/'; // * At the time of Unix
@@ -485,13 +565,18 @@ void* grfio_reads(char *fname, int *size)
entry = filelist_find(fname);
if (entry==NULL || entry->gentry<=0) { // LocalFileCheck
- char lfname[256],rname[256],*p;
+ char lfname[256],*rname,*p;
FILELIST lentry;
strncpy(lfname,fname,255);
- sprintf(rname,"%s",grfio_resnametable(fname,lfname));
- sprintf(lfname,"%s%s",data_dir,rname);
- //printf("%s\n",lfname);
+ // i hope this is the correct way =p [celest]
+ if ((rname=grfio_resnametable(fname,lfname))!=NULL) {
+ char tbuf[255];
+ //sprintf(rname,"%s",grfio_resnametable(fname,lfname));
+ sprintf(tbuf,"%s%s",data_dir,rname);
+ strcpy(lfname, tbuf);
+ //printf("%s\n",lfname);
+ }
for(p=&lfname[0];*p!=0;p++) if (*p=='\\') *p = '/'; // * At the time of Unix
@@ -504,7 +589,7 @@ void* grfio_reads(char *fname, int *size)
lentry.declen = ftell(in);
}
fseek(in,0,0); // SEEK_SET
- buf2 = calloc(lentry.declen+1024, 1);
+ buf2 = (unsigned char *)aCallocA(lentry.declen+1024, 1);
if (buf2==NULL) {
printf("file read memory allocate error : declen\n");
goto errret;
@@ -520,13 +605,13 @@ void* grfio_reads(char *fname, int *size)
} else {
printf("%s not found (grfio_reads)\n", fname);
//goto errret;
- free(buf2);
+ aFree(buf2);
return NULL;
}
}
}
if (entry!=NULL && entry->gentry>0) { // Archive[GRF] File Read
- buf = calloc(entry->srclen_aligned+1024, 1);
+ buf = (unsigned char *) aCallocA(entry->srclen_aligned+1024, 1);
if (buf==NULL) {
printf("file read memory allocate error : srclen_aligned\n");
goto errret;
@@ -536,13 +621,13 @@ void* grfio_reads(char *fname, int *size)
if(in==NULL) {
printf("%s not found (grfio_reads)\n",gfname);
//goto errret;
- free(buf);
+ aFree(buf);
return NULL;
}
fseek(in,entry->srcpos,0);
fread(buf,1,entry->srclen_aligned,in);
fclose(in);
- buf2=calloc(entry->declen+1024, 1);
+ buf2 = (unsigned char *)aCallocA(entry->declen+1024, 1);
if (buf2==NULL) {
printf("file decode memory allocate error\n");
goto errret;
@@ -561,16 +646,16 @@ void* grfio_reads(char *fname, int *size)
} else {
memcpy(buf2,buf,entry->declen);
}
- free(buf);
+ aFree(buf);
}
if (size!=NULL && entry!=NULL)
*size = entry->declen;
return buf2;
errret:
- if (buf!=NULL) free(buf);
- if (buf2!=NULL) free(buf2);
+ if (buf!=NULL) aFree(buf);
+ if (buf2!=NULL) aFree(buf2);
if (in!=NULL) fclose(in);
- exit(1); //return NULL;
+ return NULL;
}
/*==========================================
@@ -586,7 +671,7 @@ void* grfio_read(char *fname)
* Resource filename decode
*------------------------------------------
*/
-static unsigned char * decode_filename(unsigned char *buf,int len)
+static char * decode_filename(unsigned char *buf,int len)
{
int lop;
for(lop=0;lop<len;lop+=8) {
@@ -595,7 +680,7 @@ static unsigned char * decode_filename(unsigned char *buf,int len)
BitConvert4(&buf[lop]);
BitConvert(&buf[lop],BitSwapTable2);
}
- return buf;
+ return (char*)buf;
}
/*==========================================
@@ -608,12 +693,13 @@ static int grfio_entryread(char *gfname,int gentry)
int grf_size,list_size;
unsigned char grf_header[0x2e];
int lop,entry,entrys,ofs,grf_version;
- unsigned char *fname;
+ char *fname;
unsigned char *grf_filelist;
fp = fopen(gfname,"rb");
if(fp==NULL) {
- printf("%s not found (grfio_entryread)\n",gfname);
+ sprintf(tmp_output,"GRF Data File not found: '"CL_WHITE"%s"CL_RESET"'.\n",gfname);
+ ShowWarning(tmp_output);
return 1; // 1:not found error
}
@@ -621,7 +707,7 @@ static int grfio_entryread(char *gfname,int gentry)
grf_size = ftell(fp);
fseek(fp,0,0); // SEEK_SET
fread(grf_header,1,0x2e,fp);
- if(strcmp(grf_header,"Master of Magic") || fseek(fp,getlong(grf_header+0x1e),1)){ // SEEK_CUR
+ if(strcmp((const char *) grf_header,"Master of Magic") || fseek(fp,getlong(grf_header+0x1e),1)){ // SEEK_CUR
fclose(fp);
printf("%s read error\n",gfname);
return 2; // 2:file format error
@@ -631,7 +717,7 @@ static int grfio_entryread(char *gfname,int gentry)
if (grf_version==0x01) { //****** Grf version 01xx ******
list_size = grf_size-ftell(fp);
- grf_filelist = calloc(list_size, 1);
+ grf_filelist = (unsigned char *) aCallocA(list_size, 1);
if(grf_filelist==NULL){
fclose(fp);
printf("out of memory : grf_filelist\n");
@@ -654,7 +740,7 @@ static int grfio_entryread(char *gfname,int gentry)
fname = decode_filename(grf_filelist+ofs+6,grf_filelist[ofs]-6);
if(strlen(fname)>sizeof(aentry.fn)-1){
printf("file name too long : %s\n",fname);
- free(grf_filelist);
+ aFree(grf_filelist);
exit(1);
}
srclen=0;
@@ -679,7 +765,7 @@ static int grfio_entryread(char *gfname,int gentry)
aentry.srcpos = getlong(grf_filelist+ofs2+13)+0x2e;
aentry.cycle = srccount;
aentry.type = type;
- strncpy(aentry.fn,fname,sizeof(aentry.fn)-1);
+ strncpy(aentry.fn, fname,sizeof(aentry.fn)-1);
#ifdef GRFIO_LOCAL
aentry.gentry = -(gentry+1); // As Flag for making it a negative number carrying out the first time LocalFileCheck
#else
@@ -689,7 +775,7 @@ static int grfio_entryread(char *gfname,int gentry)
}
ofs = ofs2 + 17;
}
- free(grf_filelist);
+ aFree(grf_filelist);
} else if (grf_version==0x02) { //****** Grf version 02xx ******
unsigned char eheader[8];
@@ -706,15 +792,15 @@ static int grfio_entryread(char *gfname,int gentry)
return 4;
}
- rBuf = calloc( rSize , 1); // Get a Read Size
+ rBuf = (unsigned char *)aCallocA( rSize , 1); // Get a Read Size
if (rBuf==NULL) {
fclose(fp);
printf("out of memory : grf compress entry table buffer\n");
return 3;
}
- grf_filelist = calloc( eSize , 1); // Get a Extend Size
+ grf_filelist = (unsigned char *)aCallocA( eSize , 1); // Get a Extend Size
if (grf_filelist==NULL) {
- free(rBuf);
+ aFree(rBuf);
fclose(fp);
printf("out of memory : grf extract entry table buffer\n");
return 3;
@@ -723,7 +809,7 @@ static int grfio_entryread(char *gfname,int gentry)
fclose(fp);
decode_zip(grf_filelist,&eSize,rBuf,rSize); // Decode function
list_size = eSize;
- free(rBuf);
+ aFree(rBuf);
entrys = getlong(grf_header+0x26) - 7;
@@ -732,13 +818,14 @@ static int grfio_entryread(char *gfname,int gentry)
int ofs2,srclen,srccount,type;
FILELIST aentry;
- fname = grf_filelist+ofs;
+ fname = (char*)(grf_filelist+ofs);
if (strlen(fname)>sizeof(aentry.fn)-1) {
printf("grf : file name too long : %s\n",fname);
- free(grf_filelist);
+ aFree(grf_filelist);
exit(1);
}
- ofs2 = ofs+strlen(grf_filelist+ofs)+1;
+ //ofs2 = ofs+strlen((char*)(grf_filelist+ofs))+1;
+ ofs2 = ofs+strlen(fname)+1;
type = grf_filelist[ofs2+12];
if(type==1 || type==3 || type==5) {
srclen=getlong(grf_filelist+ofs2);
@@ -766,7 +853,7 @@ static int grfio_entryread(char *gfname,int gentry)
}
ofs = ofs2 + 17;
}
- free(grf_filelist);
+ aFree(grf_filelist);
} else { //****** Grf Other version ******
fclose(fp);
@@ -786,11 +873,11 @@ static int grfio_entryread(char *gfname,int gentry)
static void grfio_resourcecheck()
{
int size;
- unsigned char *buf,*ptr;
+ char *buf,*ptr;
char w1[256],w2[256],src[256],dst[256];
FILELIST *entry;
- buf=grfio_reads("data\\resnametable.txt",&size);
+ buf = (char*)grfio_reads("data\\resnametable.txt",&size);
buf[size] = 0;
for(ptr=buf;ptr-buf<size;) {
@@ -816,7 +903,7 @@ static void grfio_resourcecheck()
if (!ptr) break;
ptr++;
}
- free(buf);
+ aFree(buf);
filelist_adjust(); // Unnecessary area release of filelist
}
@@ -836,10 +923,11 @@ int grfio_add(char *fname)
exit(1);
}
- printf("%s file reading...\n",fname);
+// sprintf(tmp_output,"Reading GRF File: '%s'.\n",fname);
+// ShowStatus(tmp_output);
if (gentry_entrys>=gentry_maxentry) {
- char **new_gentry = (char**)realloc(
+ char **new_gentry = (char**)aRealloc(
(void*)gentry_table,(gentry_maxentry+GENTRY_ADDS)*sizeof(char*) );
if (new_gentry!=NULL) {
int lop;
@@ -853,7 +941,7 @@ int grfio_add(char *fname)
}
}
len = strlen( fname );
- buf = calloc(len+1, 1);
+ buf = (char*)aCallocA(len+1, 1);
if (buf==NULL) {
printf("out of memory : gentry\n");
exit(1);
@@ -879,20 +967,30 @@ void grfio_final(void)
{
int lop;
- if (filelist!=NULL) free(filelist);
+ if (filelist!=NULL) aFree(filelist);
filelist = NULL;
filelist_entrys = filelist_maxentry = 0;
if (gentry_table!=NULL) {
for(lop=0;lop<gentry_entrys;lop++) {
if (gentry_table[lop]!=NULL) {
- free(gentry_table[lop]);
+ aFree(gentry_table[lop]);
}
}
- free(gentry_table);
+ aFree(gentry_table);
}
gentry_table = NULL;
gentry_entrys = gentry_maxentry = 0;
+
+#ifdef _WIN32
+ #ifndef LOCALZLIB
+ DLL_CLOSE(zlib_dll);
+ zlib_inflateInit_ = NULL;
+ zlib_inflate = NULL;
+ zlib_inflateEnd = NULL;
+ #endif
+#endif
+
}
/*==========================================
@@ -905,6 +1003,24 @@ void grfio_init(char *fname)
char line[1024], w1[1024], w2[1024];
int result = 0, result2 = 0, result3 = 0, result4 = 0;
+#ifdef _WIN32
+ #ifndef LOCALZLIB
+ if(!zlib_dll) {
+ zlib_dll = DLL_OPEN ("zlib.dll");
+ DLL_SYM (zlib_inflateInit_, zlib_dll, "inflateInit_");
+ DLL_SYM (zlib_inflate, zlib_dll, "inflate");
+ DLL_SYM (zlib_inflateEnd, zlib_dll, "inflateEnd");
+ DLL_SYM (zlib_deflateInit_, zlib_dll, "deflateInit_");
+ DLL_SYM (zlib_deflate, zlib_dll, "deflate");
+ DLL_SYM (zlib_deflateEnd, zlib_dll, "deflateEnd");
+ if(zlib_dll == NULL) {
+ MessageBox(NULL,"Can't load zlib.dll","grfio.c",MB_OK);
+ exit(1);
+ }
+ }
+ #endif
+#endif
+
data_conf = fopen(fname, "r");
// It will read, if there is grf-files.txt.
@@ -923,7 +1039,8 @@ void grfio_init(char *fname)
}
fclose(data_conf);
- printf("read %s done\n",fname);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n",fname);
+ ShowStatus(tmp_output);
} // end of reading grf-files.txt
hashinit(); // hash table initialization
@@ -945,9 +1062,9 @@ void grfio_init(char *fname)
if (strcmp(data_dir, "") == 0) // Id data_dir doesn't exist
result4 = 1; // Data directory
-
+/*
if (result != 0 && result2 != 0 && result3 != 0 && result4 != 0) {
printf("not grf file readed exit!!\n");
exit(1); // It ends, if a resource cannot read one.
- }
+ }*/
}
diff --git a/src/common/grfio.h b/src/common/grfio.h
index 53b9da8d4..3fa257e2f 100644
--- a/src/common/grfio.h
+++ b/src/common/grfio.h
@@ -8,6 +8,9 @@ void* grfio_read(char*); // GRFIO data file read
void* grfio_reads(char*,int*); // GRFIO data file read & size get
int grfio_size(char*); // GRFIO data file size get
+int decode_zip(unsigned char *dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen);
+int encode_zip(unsigned char *dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen);
+
// Accessor to GRF filenames
char *grfio_setdatafile(const char *str);
char *grfio_setadatafile(const char *str);
diff --git a/src/common/lock.c b/src/common/lock.c
index 9a2205bf4..0258cbd2c 100644
--- a/src/common/lock.c
+++ b/src/common/lock.c
@@ -1,37 +1,55 @@
#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <windows.h>
+#define F_OK 0x0
+#define R_OK 0x4
+#endif
#include "lock.h"
+#include "showmsg.h"
+#define exists(filename) (!access(filename, F_OK))
// ‘‚«ž‚݃tƒ@ƒCƒ‹‚̕ی숗
// i‘‚«ž‚Ý‚ªI‚í‚é‚Ü‚ÅA‹Œƒtƒ@ƒCƒ‹‚ð•ÛŠÇ‚µ‚Ä‚¨‚­j
// V‚µ‚¢ƒtƒ@ƒCƒ‹‚Ì‘‚«ž‚ÝŠJŽn
-FILE* lock_fopen(const char* filename,int *info) {
+FILE* lock_fopen (const char* filename, int *info) {
char newfile[512];
FILE *fp;
- int no = 0;
+ int no = 0;
// ˆÀ‘S‚ȃtƒ@ƒCƒ‹–¼‚𓾂éiŽè”²‚«j
do {
- sprintf(newfile,"%s_%04d.tmp",filename,++no);
- } while((fp = fopen(newfile,"r")) && (fclose(fp), no<9999) );
+ sprintf(newfile, "%s_%04d.tmp", filename, ++no);
+ } while((fp = fopen(newfile,"r")) && (fclose(fp), no < 9999));
*info = no;
return fopen(newfile,"w");
}
// ‹Œƒtƒ@ƒCƒ‹‚ð휕Vƒtƒ@ƒCƒ‹‚ðƒŠƒl[ƒ€
-int lock_fclose(FILE *fp,const char* filename,int *info) {
- int ret = 0;
+int lock_fclose (FILE *fp, const char* filename, int *info) {
+ int ret = 1;
char newfile[512];
- if(fp != NULL) {
+ char oldfile[512];
+ if (fp != NULL) {
ret = fclose(fp);
- sprintf(newfile,"%s_%04d.tmp",filename,*info);
- remove(filename);
+ sprintf(newfile, "%s_%04d.tmp", filename, *info);
+ sprintf(oldfile, "%s.bak", filename); // old backup file
+
+ if (exists(oldfile)) remove(oldfile); // remove backup file if it already exists
+ rename (filename, oldfile); // backup our older data instead of deleting it
+
// ‚±‚̃^ƒCƒ~ƒ“ƒO‚Å—Ž‚¿‚é‚ÆÅˆ«B
- rename(newfile,filename);
- return ret;
- } else {
- return 1;
+ if ((ret = rename(newfile,filename)) != 0) { // rename our temporary file to its correct name
+ sprintf(tmp_output,"%s - '"CL_WHITE"%s"CL_RESET"'\n", strerror(errno), newfile);
+ ShowError(tmp_output);
+ }
}
+
+ return ret;
}
diff --git a/src/common/malloc.c b/src/common/malloc.c
index eda9bc218..b81c25ed5 100644
--- a/src/common/malloc.c
+++ b/src/common/malloc.c
@@ -1,13 +1,27 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "malloc.h"
+#ifdef MEMWATCH
+#include "memwatch.h"
+#endif
+
+// “ÆŽ©ƒƒ‚ƒŠƒ}ƒl[ƒWƒƒ‚ðŽg—p‚·‚éê‡AŽŸ‚̃Rƒƒ“ƒg‚ðŠO‚µ‚Ä‚­‚¾‚³‚¢B
+//#define USE_MEMMGR
+
+#if !defined(DMALLOC) && !defined(GCOLLECT) && !defined(BCHECK) && !defined(USE_MEMMGR)
+
void* aMalloc_( size_t size, const char *file, int line, const char *func )
{
void *ret;
-
+
// printf("%s:%d: in func %s: malloc %d\n",file,line,func,size);
+#ifdef MEMWATCH
+ ret=mwMalloc(size,file,line);
+#else
ret=malloc(size);
+#endif
if(ret==NULL){
printf("%s:%d: in func %s: malloc error out of memory!\n",file,line,func);
exit(1);
@@ -18,9 +32,13 @@ void* aMalloc_( size_t size, const char *file, int line, const char *func )
void* aCalloc_( size_t num, size_t size, const char *file, int line, const char *func )
{
void *ret;
-
+
// printf("%s:%d: in func %s: calloc %d %d\n",file,line,func,num,size);
+#ifdef MEMWATCH
+ ret=mwCalloc(num,size,file,line);
+#else
ret=calloc(num,size);
+#endif
if(ret==NULL){
printf("%s:%d: in func %s: calloc error out of memory!\n",file,line,func);
exit(1);
@@ -32,9 +50,13 @@ void* aCalloc_( size_t num, size_t size, const char *file, int line, const char
void* aRealloc_( void *p, size_t size, const char *file, int line, const char *func )
{
void *ret;
-
+
// printf("%s:%d: in func %s: realloc %p %d\n",file,line,func,p,size);
+#ifdef MEMWATCH
+ ret=mwRealloc(p,size,file,line);
+#else
ret=realloc(p,size);
+#endif
if(ret==NULL){
printf("%s:%d: in func %s: realloc error out of memory!\n",file,line,func);
exit(1);
@@ -42,3 +64,485 @@ void* aRealloc_( void *p, size_t size, const char *file, int line, const char *f
}
return ret;
}
+
+char* aStrdup_( const void *p, const char *file, int line, const char *func )
+{
+ char *ret;
+
+ // printf("%s:%d: in func %s: strdup %p\n",file,line,func,p);
+#ifdef MEMWATCH
+ ret=mwStrdup(p,file,line);
+#else
+ ret= strdup((char *) p);
+#endif
+ if(ret==NULL){
+ printf("%s:%d: in func %s: strdup error out of memory!\n",file,line,func);
+ exit(1);
+
+ }
+ return ret;
+}
+
+void aFree_( void *p, const char *file, int line, const char *func )
+{
+ // printf("%s:%d: in func %s: free %p\n",file,line,func,p);
+#ifdef MEMWATCH
+ mwFree(p,file,line);
+#else
+ free(p);
+#endif
+}
+
+#elif defined(GCOLLECT)
+
+void * _bcallocA(size_t size, size_t cnt) {
+ void *ret = aMallocA(size * cnt);
+ memset(ret, 0, size * cnt);
+ return ret;
+}
+
+void * _bcalloc(size_t size, size_t cnt) {
+ void *ret = aMalloc(size * cnt);
+ memset(ret, 0, size * cnt);
+ return ret;
+}
+
+char * _bstrdup(const char *chr) {
+ int len = strlen(chr);
+ char *ret = (char*)aMalloc(len + 1);
+ strcpy(ret, chr);
+ return ret;
+}
+
+#elif defined(USE_MEMMGR)
+
+/* USE_MEMMGR */
+
+/*
+ * ƒƒ‚ƒŠƒ}ƒl[ƒWƒƒ
+ * malloc , free ‚̈—‚ðŒø—¦“I‚Éo—ˆ‚邿‚¤‚É‚µ‚½‚à‚ÌB
+ * •¡ŽG‚Ȉ—‚ðs‚Á‚Ä‚¢‚é‚Ì‚ÅAŽáбd‚­‚Ȃ邩‚à‚µ‚ê‚Ü‚¹‚ñB
+ *
+ * ƒf[ƒ^\‘¢‚È‚Çià–¾‰ºŽè‚Å‚·‚¢‚Ü‚¹‚ñ^^; j
+ * Eƒƒ‚ƒŠ‚ð•¡”‚ÌuƒuƒƒbƒNv‚É•ª‚¯‚ÄA‚³‚ç‚ɃuƒƒbƒN‚ð•¡”‚Ìuƒ†ƒjƒbƒgv
+ * ‚É•ª‚¯‚Ä‚¢‚Ü‚·Bƒ†ƒjƒbƒg‚̃TƒCƒY‚ÍA‚PƒuƒƒbƒN‚Ì—e—ʂ𕡔ŒÂ‚ɋϓ™”z•ª
+ * ‚µ‚½‚à‚̂ł·B‚½‚Æ‚¦‚ÎA‚Pƒ†ƒjƒbƒg32KB‚Ìê‡AƒuƒƒbƒN‚P‚‚Í32Byte‚̃†
+ * ƒjƒbƒg‚ªA1024ŒÂW‚Ü‚Á‚Äo—ˆ‚Ä‚¢‚½‚èA64Byte‚̃†ƒjƒbƒg‚ª 512ŒÂW‚Ü‚Á‚Ä
+ * o—ˆ‚Ä‚¢‚½‚肵‚Ü‚·Bipadding,unit_head ‚𜂭j
+ *
+ * Eƒ†ƒjƒbƒg“¯Žm‚ÍƒŠƒ“ƒNƒŠƒXƒg(block_prev,block_next) ‚ł‚Ȃª‚èA“¯‚¶ƒTƒC
+ * ƒY‚ðŽ‚Âƒ†ƒjƒbƒg“¯Žm‚àƒŠƒ“ƒNƒŠƒXƒg(samesize_prev,samesize_nect) ‚ł‚È
+ * ‚ª‚Á‚Ä‚¢‚Ü‚·B‚»‚ê‚É‚æ‚èA•s—v‚ƂȂÁ‚½ƒƒ‚ƒŠ‚ÌÄ—˜—p‚ªŒø—¦“I‚És‚¦‚Ü‚·B
+ */
+
+/* ƒuƒƒbƒN‚É“ü‚éƒf[ƒ^—Ê */
+#define BLOCK_DATA_SIZE 80*1024
+
+/* ˆê“x‚ÉŠm•Û‚·‚éƒuƒƒbƒN‚Ì”B */
+#define BLOCK_ALLOC 32
+
+/* ƒuƒƒbƒN‚̃Aƒ‰ƒCƒƒ“ƒg */
+#define BLOCK_ALIGNMENT 64
+
+/* ƒuƒƒbƒN */
+struct block {
+ int block_no; /* ƒuƒƒbƒN”Ô† */
+ struct block* block_prev; /* ‘O‚ÉŠm•Û‚µ‚½—̈æ */
+ struct block* block_next; /* ŽŸ‚ÉŠm•Û‚µ‚½—̈æ */
+ int samesize_no; /* “¯‚¶ƒTƒCƒY‚̔Ԇ */
+ struct block* samesize_prev; /* “¯‚¶ƒTƒCƒY‚Ì‘O‚̗̈æ */
+ struct block* samesize_next; /* “¯‚¶ƒTƒCƒY‚ÌŽŸ‚̗̈æ */
+ int unit_size; /* ƒ†ƒjƒbƒg‚̃oƒCƒg” 0=–¢Žg—p */
+ int unit_hash; /* ƒ†ƒjƒbƒg‚̃nƒbƒVƒ… */
+ int unit_count; /* ƒ†ƒjƒbƒg‚Ì” */
+ int unit_used; /* Žg—pς݃†ƒjƒbƒg */
+ char data[BLOCK_DATA_SIZE];
+};
+
+struct unit_head {
+ struct block* block;
+ int size;
+ const char* file;
+ int line;
+};
+
+static struct block* block_first = NULL;
+static struct block* block_last = NULL;
+static struct block* block_unused = NULL;
+
+/* ƒ†ƒjƒbƒg‚ւ̃nƒbƒVƒ…B80KB/64Byte = 1280ŒÂ */
+static struct block* unit_first[BLOCK_DATA_SIZE/BLOCK_ALIGNMENT]; /* ʼn */
+static struct block* unit_unfill[BLOCK_DATA_SIZE/BLOCK_ALIGNMENT]; /* –„‚Ü‚Á‚ĂȂ¢ */
+static struct block* unit_last[BLOCK_DATA_SIZE/BLOCK_ALIGNMENT]; /* ÅŒã */
+
+/* ƒƒ‚ƒŠ‚ðŽg‚¢‰ñ‚¹‚È‚¢—̈æ—p‚̃f[ƒ^ */
+struct unit_head_large {
+ struct unit_head_large* prev;
+ struct unit_head_large* next;
+ struct unit_head unit_head;
+};
+static struct unit_head_large *unit_head_large_first = NULL;
+
+static struct block* block_malloc(void);
+static void block_free(struct block* p);
+static void memmgr_info(void);
+
+void* aMalloc_(size_t size, const char *file, int line, const char *func ) {
+ int i;
+ struct block *block;
+ int size_hash = (size+BLOCK_ALIGNMENT-1) / BLOCK_ALIGNMENT;
+ size = size_hash * BLOCK_ALIGNMENT; /* ƒAƒ‰ƒCƒƒ“ƒg‚Ì”{”‚ÉØ‚èã‚° */
+
+ if(size == 0) {
+ return NULL;
+ }
+
+ /* ƒuƒƒbƒN’·‚ð’´‚¦‚é—̈æ‚ÌŠm•Û‚É‚ÍAmalloc() ‚ð—p‚¢‚é */
+ /* ‚»‚ÌÛAunit_head.block ‚É NULL ‚ð‘ã“ü‚µ‚Ä‹æ•Ê‚·‚é */
+ if(size > BLOCK_DATA_SIZE - sizeof(struct unit_head)) {
+#ifdef MEMWATCH
+ struct unit_head_large* p = (struct unit_head_large*)mwMalloc(sizeof(struct unit_head_large) + size,file,line);
+#else
+ struct unit_head_large* p = (struct unit_head_large*)malloc(sizeof(struct unit_head_large) + size);
+#endif
+ if(p != NULL) {
+ p->unit_head.block = NULL;
+ p->unit_head.size = size;
+ p->unit_head.file = file;
+ p->unit_head.line = line;
+ if(unit_head_large_first == NULL) {
+ unit_head_large_first = p;
+ p->next = NULL;
+ p->prev = NULL;
+ } else {
+ unit_head_large_first->prev = p;
+ p->prev = NULL;
+ p->next = unit_head_large_first;
+ unit_head_large_first = p;
+ }
+ return (char *)p + sizeof(struct unit_head_large);
+ } else {
+ printf("MEMMGR::memmgr_alloc failed.\n");
+ exit(1);
+ }
+ }
+
+ /* “¯ˆêƒTƒCƒY‚̃uƒƒbƒN‚ªŠm•Û‚³‚ê‚Ä‚¢‚È‚¢ŽžAV‚½‚ÉŠm•Û‚·‚é */
+ if(unit_unfill[size_hash] == NULL) {
+ block = block_malloc();
+ if(unit_first[size_hash] == NULL) {
+ /* ‰‰ñŠm•Û */
+ unit_first[size_hash] = block;
+ unit_last[size_hash] = block;
+ block->samesize_no = 0;
+ block->samesize_prev = NULL;
+ block->samesize_next = NULL;
+ } else {
+ /* ˜AŒ‹ì‹Æ */
+ unit_last[size_hash]->samesize_next = block;
+ block->samesize_no = unit_last[size_hash]->samesize_no + 1;
+ block->samesize_prev = unit_last[size_hash];
+ block->samesize_next = NULL;
+ unit_last[size_hash] = block;
+ }
+ unit_unfill[size_hash] = block;
+ block->unit_size = size + sizeof(struct unit_head);
+ block->unit_count = BLOCK_DATA_SIZE / block->unit_size;
+ block->unit_used = 0;
+ block->unit_hash = size_hash;
+ /* –¢Žg—pFlag‚ð—§‚Ä‚é */
+ for(i=0;i<block->unit_count;i++) {
+ ((struct unit_head*)(&block->data[block->unit_size * i]))->block = NULL;
+ }
+ }
+ /* ƒ†ƒjƒbƒgŽg—pŒÂ”‰ÁŽZ */
+ block = unit_unfill[size_hash];
+ block->unit_used++;
+
+ /* ƒ†ƒjƒbƒg“à‚ð‘S‚ÄŽg‚¢‰Ê‚½‚µ‚½ */
+ if(block->unit_count == block->unit_used) {
+ do {
+ unit_unfill[size_hash] = unit_unfill[size_hash]->samesize_next;
+ } while(
+ unit_unfill[size_hash] != NULL &&
+ unit_unfill[size_hash]->unit_count == unit_unfill[size_hash]->unit_used
+ );
+ }
+
+ /* ƒuƒƒbƒN‚Ì’†‚̋󂫃†ƒjƒbƒg‘{õ */
+ for(i=0;i<block->unit_count;i++) {
+ struct unit_head *head = (struct unit_head*)(&block->data[block->unit_size * i]);
+ if(head->block == NULL) {
+ head->block = block;
+ head->size = size;
+ head->line = line;
+ head->file = file;
+ return (char *)head + sizeof(struct unit_head);
+ }
+ }
+ // ‚±‚±‚É—ˆ‚Ă͂¢‚¯‚È‚¢B
+ printf("MEMMGR::memmgr_malloc() serious error.\n");
+ memmgr_info();
+ exit(1);
+ return NULL;
+};
+
+void* aCalloc_(size_t num, size_t size, const char *file, int line, const char *func ) {
+ void *p = aMalloc_(num * size,file,line,func);
+ memset(p,0,num * size);
+ return p;
+}
+
+void* aRealloc_(void *memblock, size_t size, const char *file, int line, const char *func ) {
+ size_t old_size;
+ if(memblock == NULL) {
+ return aMalloc_(size,file,line,func);
+ }
+
+ old_size = ((struct unit_head *)((char *)memblock - sizeof(struct unit_head)))->size;
+ if(old_size > size) {
+ // ƒTƒCƒYk¬ -> ‚»‚̂܂ܕԂ·iŽè”²‚«j
+ return memblock;
+ } else {
+ // ƒTƒCƒYŠg‘å
+ void *p = aMalloc_(size,file,line,func);
+ if(p != NULL) {
+ memcpy(p,memblock,old_size);
+ }
+ aFree_(memblock,file,line,func);
+ return p;
+ }
+}
+
+char* aStrdup_(const void *p, const char *file, int line, const char *func ) {
+ if(p == NULL) {
+ return NULL;
+ } else {
+ int len = strlen(p);
+ char *string = (char *)aMalloc_(len + 1,file,line,func);
+ memcpy(string,p,len+1);
+ return string;
+ }
+}
+
+void aFree_(void *ptr, const char *file, int line, const char *func ) {
+ struct unit_head *head = (struct unit_head *)((char *)ptr - sizeof(struct unit_head));
+ if(ptr == NULL) {
+ return;
+ } else if(head->block == NULL && head->size > BLOCK_DATA_SIZE - sizeof(struct unit_head)) {
+ /* malloc() ‚Å’¼‚ÉŠm•Û‚³‚ꂽ—̈æ */
+ struct unit_head_large *head_large = (struct unit_head_large *)((char *)ptr - sizeof(struct unit_head_large));
+ if(head_large->prev) {
+ head_large->prev->next = head_large->next;
+ } else {
+ unit_head_large_first = head_large->next;
+ }
+ if(head_large->next) {
+ head_large->next->prev = head_large->prev;
+ }
+ free(head_large);
+ return;
+ } else {
+ /* ƒ†ƒjƒbƒg‰ð•ú */
+ struct block *block = head->block;
+ if(head->block == NULL) {
+ printf("memmgr: args of aFree is freed pointer %s line %d\n",file,line);
+ } else {
+ head->block = NULL;
+ if(--block->unit_used == 0) {
+ /* ƒuƒƒbƒN‚̉ð•ú */
+ if(unit_unfill[block->unit_hash] == block) {
+ /* ‹ó‚«ƒ†ƒjƒbƒg‚ÉŽw’肳‚ê‚Ä‚¢‚é */
+ do {
+ unit_unfill[block->unit_hash] = unit_unfill[block->unit_hash]->samesize_next;
+ } while(
+ unit_unfill[block->unit_hash] != NULL &&
+ unit_unfill[block->unit_hash]->unit_count == unit_unfill[block->unit_hash]->unit_used
+ );
+ }
+ if(block->samesize_prev == NULL && block->samesize_next == NULL) {
+ /* “Æ—§ƒuƒƒbƒN‚̉ð•ú */
+ unit_first[block->unit_hash] = NULL;
+ unit_last[block->unit_hash] = NULL;
+ unit_unfill[block->unit_hash] = NULL;
+ } else if(block->samesize_prev == NULL) {
+ /* 擪ƒuƒƒbƒN‚̉ð•ú */
+ unit_first[block->unit_hash] = block->samesize_next;
+ (block->samesize_next)->samesize_prev = NULL;
+ } else if(block->samesize_next == NULL) {
+ /* ––’[ƒuƒƒbƒN‚̉ð•ú */
+ unit_last[block->unit_hash] = block->samesize_prev;
+ (block->samesize_prev)->samesize_next = NULL;
+ } else {
+ /* ’†ŠÔƒuƒƒbƒN‚̉ð•ú */
+ (block->samesize_next)->samesize_prev = block->samesize_prev;
+ (block->samesize_prev)->samesize_next = block->samesize_next;
+ }
+ block_free(block);
+ } else {
+ /* ‹ó‚«ƒ†ƒjƒbƒg‚ÌÄÝ’è */
+ if(
+ unit_unfill[block->unit_hash] == NULL ||
+ unit_unfill[block->unit_hash]->samesize_no > block->samesize_no
+ ) {
+ unit_unfill[block->unit_hash] = block;
+ }
+ }
+ }
+ }
+}
+
+/* Œ»Ý‚Ì󋵂ð•\ަ‚·‚é */
+static void memmgr_info(void) {
+ int i;
+ struct block *p;
+ printf("** Memory Maneger Information **\n");
+ if(block_first == NULL) {
+ printf("Uninitialized.\n");
+ return;
+ }
+ printf(
+ "Blocks: %04u , BlockSize: %06u Byte , Used: %08uKB\n",
+ block_last->block_no+1,sizeof(struct block),
+ (block_last->block_no+1) * sizeof(struct block) / 1024
+ );
+ p = block_first;
+ for(i=0;i<=block_last->block_no;i++) {
+ printf(" Block #%04u : ",p->block_no);
+ if(p->unit_size == 0) {
+ printf("unused.\n");
+ } else {
+ printf(
+ "size: %05u byte. used: %04u/%04u prev:",
+ p->unit_size - sizeof(struct unit_head),p->unit_used,p->unit_count
+ );
+ if(p->samesize_prev == NULL) {
+ printf("NULL");
+ } else {
+ printf("%04u",(p->samesize_prev)->block_no);
+ }
+ printf(" next:");
+ if(p->samesize_next == NULL) {
+ printf("NULL");
+ } else {
+ printf("%04u",(p->samesize_next)->block_no);
+ }
+ printf("\n");
+ }
+ p = p->block_next;
+ }
+}
+
+/* ƒuƒƒbƒN‚ðŠm•Û‚·‚é */
+static struct block* block_malloc(void) {
+ if(block_unused != NULL) {
+ /* ƒuƒƒbƒN—p‚̗̈æ‚ÍŠm•ÛÏ‚Ý */
+ struct block* ret = block_unused;
+ do {
+ block_unused = block_unused->block_next;
+ } while(block_unused != NULL && block_unused->unit_size != 0);
+ return ret;
+ } else {
+ /* ƒuƒƒbƒN—p‚̗̈æ‚ðV‚½‚ÉŠm•Û‚·‚é */
+ int i;
+ int block_no;
+ struct block* p = (struct block *)calloc(sizeof(struct block),BLOCK_ALLOC);
+ if(p == NULL) {
+ printf("MEMMGR::block_alloc failed.\n");
+ exit(1);
+ }
+ if(block_first == NULL) {
+ /* ‰‰ñŠm•Û */
+ block_no = 0;
+ block_first = p;
+ } else {
+ block_no = block_last->block_no + 1;
+ block_last->block_next = p;
+ p->block_prev = block_last;
+ }
+ block_last = &p[BLOCK_ALLOC - 1];
+ /* ƒuƒƒbƒN‚ð˜AŒ‹‚³‚¹‚é */
+ for(i=0;i<BLOCK_ALLOC;i++) {
+ if(i != 0) {
+ p[i].block_prev = &p[i-1];
+ }
+ if(i != BLOCK_ALLOC -1) {
+ p[i].block_next = &p[i+1];
+ }
+ p[i].block_no = block_no + i;
+ }
+
+ /* –¢Žg—pƒuƒƒbƒN‚ւ̃|ƒCƒ“ƒ^‚ðXV */
+ block_unused = &p[1];
+ p->unit_size = 1;
+ return p;
+ }
+}
+
+static void block_free(struct block* p) {
+ /* free() ‚¹‚¸‚ÉA–¢Žg—pƒtƒ‰ƒO‚ð•t‚¯‚邾‚¯ */
+ p->unit_size = 0;
+ /* –¢Žg—pƒ|ƒCƒ“ƒ^[‚ðXV‚·‚é */
+ if(block_unused == NULL) {
+ block_unused = p;
+ } else if(block_unused->block_no > p->block_no) {
+ block_unused = p;
+ }
+}
+
+static char memmer_logfile[128];
+
+static FILE* memmgr_log(void) {
+ FILE *fp = fopen(memmer_logfile,"w");
+ if(!fp) { fp = stdout; }
+ fprintf(fp,"memmgr: memory leaks found\n");
+ return fp;
+}
+
+static void memmer_exit(void) {
+ FILE *fp = NULL;
+ int i;
+ int count = 0;
+ struct block *block = block_first;
+ struct unit_head_large *large = unit_head_large_first;
+ while(block) {
+ if(block->unit_size) {
+ if(!fp) { fp = memmgr_log(); }
+ for(i=0;i<block->unit_count;i++) {
+ struct unit_head *head = (struct unit_head*)(&block->data[block->unit_size * i]);
+ if(head->block != NULL) {
+ fprintf(
+ fp,"%04d : %s line %d size %d\n",++count,
+ head->file,head->line,head->size
+ );
+ }
+ }
+ }
+ block = block->block_next;
+ }
+ while(large) {
+ if(!fp) { fp = memmgr_log(); }
+ fprintf(
+ fp,"%04d : %s line %d size %d\n",++count,
+ large->unit_head.file,
+ large->unit_head.line,large->unit_head.size
+ );
+ large = large->next;
+ }
+ if(!fp) {
+ printf("memmgr: no memory leaks found.\n");
+ } else {
+ printf("memmgr: memory leaks found.\n");
+ fclose(fp);
+ }
+}
+#endif
+
+int do_init_memmgr(const char* file) {
+ #ifdef USE_MEMMGR
+ sprintf(memmer_logfile,"%s.log",file);
+ atexit(memmer_exit);
+ printf("memmgr: initialised: %s\n",memmer_logfile);
+ #endif
+ return 0;
+}
diff --git a/src/common/malloc.h b/src/common/malloc.h
index 3733a5e55..c233adb8d 100644
--- a/src/common/malloc.h
+++ b/src/common/malloc.h
@@ -3,6 +3,49 @@
#include <stdlib.h>
+#if defined(DMALLOC)
+
+# include "dmalloc.h"
+# define aMalloc(size) \
+ dmalloc_malloc(__FILE__, __LINE__, (size), DMALLOC_FUNC_MALLOC, 0, 0)
+# define aMallocA(size) \
+ dmalloc_malloc(__FILE__, __LINE__, (size), DMALLOC_FUNC_MALLOC, 0, 0)
+# define aCallocA(count,size) \
+ dmalloc_malloc(__FILE__, __LINE__, (count)*(size), DMALLOC_FUNC_CALLOC, 0, 0)
+# define aCalloc(count,size) \
+ dmalloc_malloc(__FILE__, __LINE__, (count)*(size), DMALLOC_FUNC_CALLOC, 0, 0)
+# define aRealloc(ptr,size) \
+ dmalloc_realloc(__FILE__, __LINE__, (ptr), (size), DMALLOC_FUNC_REALLOC, 0)
+# define aFree(ptr) free(ptr)
+# define aStrdup(ptr) strdup(ptr)
+
+#elif defined(GCOLLECT)
+
+# include "gc.h"
+# define aMalloc(n) GC_MALLOC(n)
+# define aMallocA(n) GC_MALLOC_ATOMIC(n)
+# define aCallocA(m,n) _bcallocA(m,n)
+# define aCalloc(m,n) _bcalloc(m,n)
+# define aRealloc(p,n) GC_REALLOC(p,n)
+# define aFree(n) GC_FREE(n)
+# define aStrdup(n) _bstrdup(n)
+
+ extern void * _bcalloc(size_t, size_t);
+ extern void * _bcallocA(size_t, size_t);
+ extern char * _bstrdup(const char *);
+
+#elif defined(BCHECK)
+
+# define aMalloc(n) malloc(n)
+# define aMallocA(n) malloc(n)
+# define aCalloc(m,n) calloc(m,n)
+# define aCallocA(m,n) calloc(m,n)
+# define aRealloc(p,n) realloc(p,n)
+# define aFree(n) free(n)
+# define aStrdup(n) strdup(n)
+
+#else
+
#if __STDC_VERSION__ < 199901L
# if __GNUC__ >= 2
# define __func__ __FUNCTION__
@@ -11,15 +54,24 @@
# endif
#endif
-#define ALC_MARK __FILE__, __LINE__, __func__
+# define ALC_MARK __FILE__, __LINE__, __func__
-void* aMalloc_( size_t size, const char *file, int line, const char *func );
-void* aCalloc_( size_t num, size_t size, const char *file, int line, const char *func );
-void* aRealloc_( void *p, size_t size, const char *file, int line, const char *func );
+ void* aMalloc_( size_t size, const char *file, int line, const char *func );
+ void* aCalloc_( size_t num, size_t size, const char *file, int line, const char *func );
+ void* aRealloc_( void *p, size_t size, const char *file, int line, const char *func );
+ void aFree_( void *p, const char *file, int line, const char *func );
+ char* aStrdup_( const void *p, const char *file, int line, const char *func );
-#define aMalloc(n) aMalloc_(n,ALC_MARK)
-#define aCalloc(m,n) aCalloc_(m,n,ALC_MARK)
-#define aRealloc(p,n) aRealloc_(p,n,ALC_MARK)
+# define aMalloc(n) aMalloc_(n,ALC_MARK)
+# define aMallocA(n) aMalloc_(n,ALC_MARK)
+# define aCalloc(m,n) aCalloc_(m,n,ALC_MARK)
+# define aCallocA(m,n) aCalloc_(m,n,ALC_MARK)
+# define aRealloc(p,n) aRealloc_(p,n,ALC_MARK)
+# define aStrdup(p) aStrdup_(p,ALC_MARK)
+# define aFree(p) do { aFree_(p,ALC_MARK); if(p != NULL) { p = NULL; } } while(0)
+
+#endif
+int do_init_memmgr(const char* file);
#endif
diff --git a/src/common/mmo.h b/src/common/mmo.h
index f6150d39a..1602c5655 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -7,6 +7,20 @@
#include <time.h>
#include "utils.h" // _WIN32
+#if ! defined(Assert)
+#if defined(RELEASE)
+#define Assert(EX)
+#else
+// extern "C" {
+#include <assert.h>
+// }
+#if defined(_WIN32)
+#include <crtdbg.h>
+#endif
+#define Assert(EX) assert(EX)
+#endif
+#endif /* ! defined(Assert) */
+
#ifdef CYGWIN
// txt‚âlog‚Ȃǂ̑‚«o‚·ƒtƒ@ƒCƒ‹‚̉üsƒR[ƒh
#define RETCODE "\r\n" // (CR/LFFWindowsŒn)
@@ -29,7 +43,7 @@
#define MAX_AMOUNT 30000
#define MAX_ZENY 1000000000 // 1G zeny
#define MAX_CART 100
-#define MAX_SKILL 450
+#define MAX_SKILL 650
#define GLOBAL_REG_NUM 96
#define ACCOUNT_REG_NUM 16
#define ACCOUNT_REG2_NUM 16
@@ -39,7 +53,7 @@
#define MAX_STORAGE 300
#define MAX_GUILD_STORAGE 1000
#define MAX_PARTY 12
-#define MAX_GUILD 36 // increased max guild members to accomodate for +2 increase for extension levels [Valaris] (removed) [PoW]
+#define MAX_GUILD 16+10*6 // increased max guild members to accomodate for +6 increase for extension levels [Lupus]
#define MAX_GUILDPOSITION 20 // increased max guild positions to accomodate for all members [Valaris] (removed) [PoW]
#define MAX_GUILDEXPLUSION 32
#define MAX_GUILDALLIANCE 16
@@ -54,8 +68,6 @@
#define MIN_CLOTH_COLOR battle_config.min_cloth_color
#define MAX_CLOTH_COLOR battle_config.max_cloth_color
-#define MIN_CHAR_ID 150000 // shouldn't ever be changed, the client requires this min value [Ajarn]
-
// for produce
#define MIN_ATTRIBUTE 0
#define MAX_ATTRIBUTE 4
@@ -102,7 +114,7 @@ struct s_pet {
int account_id;
int char_id;
int pet_id;
- short class;
+ short class_;
short level;
short egg_id;//pet egg id
short equip;//pet equip name_id
@@ -117,10 +129,13 @@ struct mmo_charstatus {
int char_id;
int account_id;
int partner_id;
+ int father;
+ int mother;
+ int child;
int base_exp,job_exp,zeny;
- short class;
+ short class_;
short status_point,skill_point;
int hp,max_hp,sp,max_sp;
short option,karma,manner;
@@ -131,7 +146,7 @@ struct mmo_charstatus {
short head_top,head_mid,head_bottom;
char name[24];
- unsigned char base_level,job_level;
+ unsigned int base_level,job_level;
short str,agi,vit,int_,dex,luk;
unsigned char char_num,sex;
@@ -154,17 +169,18 @@ struct mmo_charstatus {
};
struct storage {
+ int dirty;
int account_id;
short storage_status;
short storage_amount;
- struct item storage[MAX_STORAGE];
+ struct item storage_[MAX_STORAGE];
};
struct guild_storage {
int guild_id;
short storage_status;
short storage_amount;
- struct item storage[MAX_GUILD_STORAGE];
+ struct item storage_[MAX_GUILD_STORAGE];
};
struct map_session_data;
@@ -185,13 +201,13 @@ struct party {
int party_id;
char name[24];
int exp;
- int item;
+ int item, itemc;
struct party_member member[MAX_PARTY];
};
struct guild_member {
int account_id, char_id;
- short hair,hair_color,gender,class,lv;
+ short hair,hair_color,gender,class_,lv;
int exp,exp_payper;
short online,position;
int rsv1,rsv2;
@@ -267,8 +283,8 @@ struct guild_castle {
int Ghp4;
int Ghp5;
int Ghp6;
- int Ghp7;
- int GID0;
+ int Ghp7;
+ int GID0;
int GID1;
int GID2;
int GID3;
@@ -313,23 +329,25 @@ enum {
GD_DEVELOPMENT=10014,
};
-#ifndef _WIN32
-#ifndef strcmpi
-#define strcmpi strcasecmp
-#endif
-#ifndef stricmp
-#define stricmp strcasecmp
-#endif
-#ifndef strncmpi
-#define strncmpi strncasecmp
-#endif
-#ifndef strnicmp
-#define strnicmp strncasecmp
-#endif
-#ifndef strrchr
-#define strrchr rindex
-#endif
-
+#ifndef __WIN32
+ #ifndef strcmpi
+ #define strcmpi strcasecmp
+ #endif
+ #ifndef stricmp
+ #define stricmp strcasecmp
+ #endif
+ #ifndef strncmpi
+ #define strncmpi strncasecmp
+ #endif
+ #ifndef strnicmp
+ #define strnicmp strncasecmp
+ #endif
+#else
+ #define snprintf _snprintf
+ #define vsnprintf _vsnprintf
+ #ifndef strncmpi
+ #define strncmpi strnicmp
+ #endif
#endif
#endif // _MMO_H_
diff --git a/src/common/nullpo.h b/src/common/nullpo.h
index 11283f941..0b9a9f7a5 100644
--- a/src/common/nullpo.h
+++ b/src/common/nullpo.h
@@ -87,6 +87,8 @@
#define nullpo_retr(ret, t) \
if (nullpo_chk(NLP_MARK, (void *)(t))) {return(ret);}
+#define nullpo_retb(t) \
+ if (nullpo_chk(NLP_MARK, (void *)(t))) {break;}
// ‰Â•ψø”ƒ}ƒNƒ‚ÉŠÖ‚·‚éðŒƒRƒ“ƒpƒCƒ‹
#if __STDC_VERSION__ >= 199901L
@@ -100,6 +102,9 @@
#define nullpo_retr_f(ret, t, fmt, ...) \
if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {return(ret);}
+#define nullpo_retb_f(t, fmt, ...) \
+ if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {break;}
+
#elif __GNUC__ >= 2
/* GCC—p */
#define nullpo_ret_f(t, fmt, args...) \
@@ -111,6 +116,9 @@
#define nullpo_retr_f(ret, t, fmt, args...) \
if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {return(ret);}
+#define nullpo_retb_f(t, fmt, args...) \
+ if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {break;}
+
#else
/* ‚»‚Ì‘¼‚Ìê‡EEE orz */
@@ -127,6 +135,7 @@
#define nullpo_ret(t) if((t)){;}
#define nullpo_retv(t) if((t)){;}
#define nullpo_retr(ret, t) if((t)){;}
+#define nullpo_retb(t) if((t)){;}
// ‰Â•ψø”ƒ}ƒNƒ‚ÉŠÖ‚·‚éðŒƒRƒ“ƒpƒCƒ‹
#if __STDC_VERSION__ >= 199901L
@@ -134,12 +143,14 @@
#define nullpo_ret_f(t, fmt, ...) if((t)){;}
#define nullpo_retv_f(t, fmt, ...) if((t)){;}
#define nullpo_retr_f(ret, t, fmt, ...) if((t)){;}
+#define nullpo_retb_f(t, fmt, ...) if((t)){;}
#elif __GNUC__ >= 2
/* GCC—p */
#define nullpo_ret_f(t, fmt, args...) if((t)){;}
#define nullpo_retv_f(t, fmt, args...) if((t)){;}
#define nullpo_retr_f(ret, t, fmt, args...) if((t)){;}
+#define nullpo_retb_f(t, fmt, args...) if((t)){;}
#else
/* ‚»‚Ì‘¼‚Ìê‡EEE orz */
diff --git a/src/common/showmsg.c b/src/common/showmsg.c
index b65181f3a..24d51d2dc 100644
--- a/src/common/showmsg.c
+++ b/src/common/showmsg.c
@@ -1,65 +1,68 @@
#include <stdio.h>
-#include <stdlib.h>
#include <string.h>
+#include <stdarg.h>
#include "showmsg.h"
char tmp_output[1024] = {"\0"};
-int _ShowMessage(const char *string, enum msg_type flag){ // by MC Cameri
- /*
- _ShowMessage MUST be used instead of printf as of 10/24/2004.
- Return: 0 = Successful, 1 = Failed.
- */
+// by MC Cameri
+int _vShowMessage(enum msg_type flag, const char *string, va_list ap)
+{
+ // _ShowMessage MUST be used instead of printf as of 10/24/2004.
+ // Return: 0 = Successful, 1 = Failed.
// int ret = 0;
char prefix[40];
- char *output;
- if (strlen(string) <= 0) {
- ShowError("Empty string passed to ShowMessage().\n");
+
+ if (!string || strlen(string) <= 0) {
+ printf("Empty string passed to _ShowMessage().\n");
return 1;
}
switch (flag) {
+ case MSG_NONE: // direct printf replacement
+ break;
case MSG_STATUS: //Bright Green (To inform about good things)
- strcpy(prefix,"\033[1;32m[Status]\033[0;0m: ");
+ strcpy(prefix,CL_GREEN"[Status]"CL_RESET":");
break;
-/* //Do we really need this now? [MC Cameri]
case MSG_SQL: //Bright Violet (For dumping out anything related with SQL)
- strcpy(prefix,"\033[1;35m[SQL]\033[0;0m: ");
+ strcpy(prefix,CL_MAGENTA"[SQL]"CL_RESET":");
break;
-*/
- case MSG_INFORMATION: //Bright Blue (Variable information)
- strcpy(prefix,"\033[1;34m[Info]\033[0;0m: ");
+ case MSG_INFORMATION: //Bright White (Variable information)
+ strcpy(prefix,CL_WHITE"[Info]"CL_RESET":");
break;
case MSG_NOTICE: //Bright White (Less than a warning)
- strcpy(prefix,"\033[1;29m[Notice]\033[0;0m: ");
+ strcpy(prefix,CL_WHITE"[Notice]"CL_RESET":");
break;
case MSG_WARNING: //Bright Yellow
- strcpy(prefix,"\033[1;33m[Warning]\033[0;0m: ");
+ strcpy(prefix,CL_YELLOW"[Warning]"CL_RESET":");
+ break;
+ case MSG_DEBUG: //Bright Cyan, important stuff!
+ strcpy(prefix,CL_CYAN"[Debug]"CL_RESET":");
break;
case MSG_ERROR: //Bright Red (Regular errors)
- strcpy(prefix,"\033[1;31m[Error]\033[0;0m: ");
+ strcpy(prefix,CL_RED"[Error]"CL_RESET":");
break;
case MSG_FATALERROR: //Bright Red (Fatal errors, abort(); if possible)
- strcpy(prefix,"\033[1;31m[Fatal Error]\033[0;0m: ");
+ strcpy(prefix,CL_RED"[Fatal Error]"CL_RESET":");
break;
default:
- ShowError("In function _ShowMessage() -> Invalid flag passed.\n");
+ printf("In function _ShowMessage() -> Invalid flag passed.\n");
return 1;
}
- output = (char*)malloc(sizeof(char)*(strlen(prefix)+strlen(string))+1);
- if (output == NULL) {
- return 1;
-// abort(); // Kill server?
+
+ if (!(flag == MSG_DEBUG && !SHOW_DEBUG_MSG)) {
+ if (flag != MSG_NONE)
+ printf ("%s ", prefix);
+ vprintf (string, ap);
+ fflush (stdout);
}
- strcpy(output,prefix);
- strcat(output,string);
- printf(output);
- fflush(stdout);
+
+ va_end(ap);
/*
if ((core_config.debug_output_level > -1) && (flag >= core_config.debug_output_level)) {
FILE *fp;
fp=fopen(OUTPUT_MESSAGES_LOG,"a");
if (fp == NULL) {
- printf("\033[1;31m[Error]\033[0;0m: Could not open \033[1;29m%s\033[0;0m, file not found.\n",OUTPUT_MESSAGES_LOG);
+ printf(CL_RED"[Error]"CL_RESET": Could not open '"CL_WHITE"%s"CL_RESET"', file not found.\n",OUTPUT_MESSAGES_LOG);
fflush(stdout);
return;
}
@@ -71,3 +74,67 @@ int _ShowMessage(const char *string, enum msg_type flag){ // by MC Cameri
*/
return 0;
}
+
+int _ShowMessage(enum msg_type flag, const char *string, ...)
+{
+ va_list ap;
+
+ va_start(ap, string);
+ return _vShowMessage(flag, string, ap);
+}
+
+// direct printf replacement
+int ShowMessage(const char *string, ...) {
+ va_list ap;
+
+ va_start(ap, string);
+ return _vShowMessage(MSG_NONE, string, ap);
+}
+int ShowStatus(const char *string, ...) {
+ va_list ap;
+
+ va_start(ap, string);
+ return _vShowMessage(MSG_STATUS, string, ap);
+}
+int ShowSQL(const char *string, ...) {
+ va_list ap;
+
+ va_start(ap, string);
+ return _vShowMessage(MSG_SQL, string, ap);
+}
+int ShowInfo(const char *string, ...) {
+ va_list ap;
+
+ va_start(ap, string);
+ return _vShowMessage(MSG_INFORMATION, string, ap);
+}
+int ShowNotice(const char *string, ...) {
+ va_list ap;
+
+ va_start(ap, string);
+ return _vShowMessage(MSG_NOTICE, string, ap);
+}
+int ShowWarning(const char *string, ...) {
+ va_list ap;
+
+ va_start(ap, string);
+ return _vShowMessage(MSG_WARNING, string, ap);
+}
+int ShowDebug(const char *string, ...) {
+ va_list ap;
+
+ va_start(ap, string);
+ return _vShowMessage(MSG_DEBUG, string, ap);
+}
+int ShowError(const char *string, ...) {
+ va_list ap;
+
+ va_start(ap, string);
+ return _vShowMessage(MSG_ERROR, string, ap);
+}
+int ShowFatalError(const char *string, ...) {
+ va_list ap;
+
+ va_start(ap, string);
+ return _vShowMessage(MSG_FATALERROR, string, ap);
+}
diff --git a/src/common/showmsg.h b/src/common/showmsg.h
index 1c4a2dfcb..b5f4d4bfd 100644
--- a/src/common/showmsg.h
+++ b/src/common/showmsg.h
@@ -1,50 +1,57 @@
#ifndef _SHOWMSG_H_
#define _SHOWMSG_H_
-extern char tmp_output[1024];
-
-enum msg_type {MSG_STATUS,/* MSG_SQL, */MSG_INFORMATION,MSG_NOTICE,MSG_WARNING,MSG_ERROR,MSG_FATALERROR};
-
-extern int _ShowMessage(const char *string, enum msg_type flag);
-
-/* MSG_XX */
- #define ShowMsg(string,flag) _ShowMessage(string,flag)
-// #define DisplayMsg(string,flag) _ShowMessage(string,flag)
- #define ShowMessage(string,flag) _ShowMessage(string,flag)
-
-/* MSG_STATUS */
- #define ShowStatus(string) _ShowMessage(string,MSG_STATUS)
-// #define DisplayStatus(string) _ShowMessage(string,MSG_STATUS)
-
-/* MSG_SQL*/
-// #define ShowSQL(string) _ShowMessage(string,MSG_SQL)
-// #define DisplaySQL(string) _ShowMessage(string,MSG_SQL)
-
-/* MSG_INFORMATION */
- #define ShowInfo(string) _ShowMessage(string,MSG_INFORMATION)
-// #define DisplayInfo(string) _ShowMessage(string,MSG_INFORMATION)
-// #define ShowInformation(string) _ShowMessage(string,MSG_INFORMATION)
-// #define DisplayInformation(string) _ShowMessage(string,MSG_INFORMATION)
-
-/* MSG_NOTICE */
- #define ShowNotice(string) _ShowMessage(string,MSG_NOTICE)
-// #define DisplayNotice(string) _ShowMessage(string,MSG_NOTICE)
-
-/* */
- #define ShowWarning(string) _ShowMessage(string,MSG_WARNING)
-// #define DisplayWarning(string) _ShowMessage(string,MSG_WARNING)
-// #define Warn(string) _ShowMessage(string,MSG_WARNING)
+//davidsiaw, 'lookee' here!
+#define SHOW_DEBUG_MSG 1
+
+#ifdef _WIN32
+#define CL_RESET ""
+#define CL_NORMAL CL_RESET
+#define CL_NONE CL_RESET
+#define CL_WHITE ""
+#define CL_GRAY ""
+#define CL_RED ""
+#define CL_GREEN ""
+#define CL_YELLOW ""
+#define CL_BLUE ""
+#define CL_MAGENTA ""
+#define CL_CYAN ""
+#else
+#define CL_RESET "\033[0;0m"
+#define CL_NORMAL CL_RESET
+#define CL_NONE CL_RESET
+#define CL_WHITE "\033[1;29m"
+#define CL_GRAY "\033[1;30m"
+#define CL_RED "\033[1;31m"
+#define CL_GREEN "\033[1;32m"
+#define CL_YELLOW "\033[1;33m"
+#define CL_BLUE "\033[1;34m"
+#define CL_MAGENTA "\033[1;35m"
+#define CL_CYAN "\033[1;36m"
+#endif
-/* MSG_ERROR */
- #define ShowError(string) _ShowMessage(string,MSG_ERROR)
-// #define DisplayError(string) _ShowMessage(string,MSG_ERROR)
-// #define OutputError(string) _ShowMessage(string,MSG_ERROR)
+extern char tmp_output[1024];
-/* MSG_FATALERROR */
- #define ShowFatalError(string) _ShowMessage(string,MSG_FATALERROR)
-// #define DisplayFatalError(string) _ShowMessage(string,MSG_ERROR)
-// #define Terminate(string) _ShowMessage(string,MSG_FATALERROR)
-// #define Kill(string) _ShowMessage(string,MSG_FATALERROR)
-// #define AbortEx(string) _ShowMessage(string,MSG_FATALERROR)
+enum msg_type {
+ MSG_NONE,
+ MSG_STATUS,
+ MSG_SQL,
+ MSG_INFORMATION,
+ MSG_NOTICE,
+ MSG_WARNING,
+ MSG_DEBUG,
+ MSG_ERROR,
+ MSG_FATALERROR
+};
+
+extern int ShowMessage(const char *, ...);
+extern int ShowStatus(const char *, ...);
+extern int ShowSQL(const char *, ...);
+extern int ShowInfo(const char *, ...);
+extern int ShowNotice(const char *, ...);
+extern int ShowWarning(const char *, ...);
+extern int ShowDebug(const char *, ...);
+extern int ShowError(const char *, ...);
+extern int ShowFatalError(const char *, ...);
#endif
diff --git a/src/common/socket.c b/src/common/socket.c
index 4afcf50d4..64f660a11 100644
--- a/src/common/socket.c
+++ b/src/common/socket.c
@@ -3,11 +3,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
+#include <errno.h>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
+#include <io.h>
+typedef int socklen_t;
#else
#include <sys/socket.h>
#include <netinet/in.h>
@@ -16,14 +19,21 @@
#include <sys/time.h>
#include <unistd.h>
#include <sys/ioctl.h>
+
+#ifndef SIOCGIFCONF
+#include <sys/sockio.h> // SIOCGIFCONF on Solaris, maybe others? [Shinomori]
+#endif
+
#endif
#include <fcntl.h>
#include <string.h>
-#include "mmo.h" // [Valaris] thanks to fov
#include "socket.h"
-#include "utils.h"
+#include "../common/dll.h"
+#include "../common/mmo.h" // [Valaris] thanks to fov
+#include "../common/timer.h"
+#include "../common/utils.h"
#ifdef MEMWATCH
#include "memwatch.h"
@@ -31,6 +41,27 @@
fd_set readfds;
int fd_max;
+time_t tick_;
+time_t stall_time_ = 60;
+int ip_rules = 1;
+
+// #define UPNP
+
+#ifdef UPNP
+#if defined(CYGWIN) || defined(_WIN32)
+DLL upnp_dll;
+int (*upnp_init)();
+int (*upnp_final)();
+int (*firewall_addport)(char *desc, int port);
+int (*upnp_addport)(char *desc, char *ip, int port);
+extern char *argp;
+
+int release_mappings = 1;
+int close_ports = 1;
+#else
+#error This doesnt work with non-Windows yet
+#endif
+#endif
int rfifo_size = 65536;
int wfifo_size = 65536;
@@ -39,6 +70,8 @@ int wfifo_size = 65536;
#define TCP_FRAME_LEN 1053
#endif
+#define CONVIP(ip) ip&0xFF,(ip>>8)&0xFF,(ip>>16)&0xFF,ip>>24
+
struct socket_data *session[FD_SETSIZE];
static int null_parse(int fd);
@@ -46,6 +79,7 @@ static int (*default_func_parse)(int) = null_parse;
static int null_console_parse(char *buf);
static int (*default_console_parse)(char*) = null_console_parse;
+static int connect_check(unsigned int ip);
/*======================================
* CORE : Set function
@@ -56,7 +90,10 @@ void set_defaultparse(int (*defaultparse)(int))
default_func_parse = defaultparse;
}
-#ifdef NSOCKET
+void set_nonblocking(int fd, int yes) {
+ setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,(char *)&yes,sizeof yes);
+}
+
static void setsocketopts(int fd)
{
int yes = 1; // reuse fix
@@ -65,13 +102,12 @@ static void setsocketopts(int fd)
#ifdef SO_REUSEPORT
setsockopt(fd,SOL_SOCKET,SO_REUSEPORT,(char *)&yes,sizeof yes);
#endif
- setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,(char *)&yes,sizeof yes);
+ set_nonblocking(fd, yes);
setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *) &wfifo_size , sizeof(rfifo_size ));
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *) &rfifo_size , sizeof(rfifo_size ));
}
-#endif /* NSOCKET */
/*======================================
* CORE : Socket Sub Function
*--------------------------------------
@@ -98,19 +134,10 @@ static int recv_to_fifo(int fd)
//{ int i; printf("recv %d : ",fd); for(i=0;i<len;i++){ printf("%02x ",RFIFOB(fd,session[fd]->rdata_size+i)); } printf("\n");}
if(len>0){
session[fd]->rdata_size+=len;
+ session[fd]->rdata_tick = tick_;
} else if(len<=0){
// value of connection is not necessary the same
-// if (fd == 4) // Removed [Yor]
-// printf("Char-Server Has Disconnected.\n");
-// else if (fd == 5) // Removed [Yor]
-// printf("Attempt To Log In Successful.\n");
-// else if (fd == 7) // Removed [Yor]
-// printf("Char-Server Has Disconnected.\n");
-// else if (fd == 8) // Removed [Valaris]
-// printf("%s has logged off your server.\n",RFIFOP(fd,6)); // Removed [Valaris]
-
-// else if (fd != 8) // [Valaris]
- printf("set eof : connection #%d\n", fd);
+// printf("set eof : connection #%d\n", fd);
session[fd]->eof=1;
}
return 0;
@@ -121,8 +148,10 @@ static int send_from_fifo(int fd)
int len;
//printf("send_from_fifo : %d\n",fd);
- if(session[fd]->eof)
+ if(session[fd]->eof || session[fd]->wdata == 0)
return -1;
+ if (session[fd]->wdata_size == 0)
+ return 0;
#ifdef _WIN32
len=send(fd, session[fd]->wdata,session[fd]->wdata_size, 0);
@@ -141,13 +170,22 @@ static int send_from_fifo(int fd)
} else {
session[fd]->wdata_size=0;
}
- } else {
- printf("set eof :%d\n",fd);
+ } else if (errno != EAGAIN) {
+// printf("set eof :%d\n",fd);
session[fd]->eof=1;
}
return 0;
}
+void flush_fifos()
+{
+ int i;
+ for(i=0;i<fd_max;i++)
+ if(session[i] != NULL &&
+ session[i]->func_send == send_from_fifo)
+ send_from_fifo(i);
+}
+
static int null_parse(int fd)
{
printf("null_parse : %d\n",fd);
@@ -165,45 +203,40 @@ static int connect_client(int listen_fd)
int fd;
struct sockaddr_in client_address;
int len;
+#ifndef _WIN32
int result;
-#ifndef NSOCKET
- int yes = 1; // reuse fix
-#endif /* not NSOCKET */
+#endif
//printf("connect_client : %d\n",listen_fd);
len=sizeof(client_address);
- fd=accept(listen_fd,(struct sockaddr*)&client_address,&len);
+ fd = accept(listen_fd,(struct sockaddr*)&client_address,(socklen_t*)&len);
if(fd_max<=fd) fd_max=fd+1;
-#ifndef NSOCKET
- setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&yes,sizeof yes);
-#ifdef SO_REUSEPORT
- setsockopt(fd,SOL_SOCKET,SO_REUSEPORT,(char *)&yes,sizeof yes);
-#endif
- setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,(char *)&yes,sizeof yes);
-#else /* NSOCKET */
setsocketopts(fd);
-#endif /* NSOCKET */
- if(fd==-1)
+ if(fd==-1) {
perror("accept");
- else
+ return -1;
+ } else if (ip_rules && !connect_check(*(unsigned int*)(&client_address.sin_addr))) {
+ close(fd);
+ return -1;
+ } else
FD_SET(fd,&readfds);
#ifdef _WIN32
- {
- unsigned long val = 1;
- ioctlsocket(fd, FIONBIO, &val);
- }
+ {
+ unsigned long val = 1;
+ ioctlsocket(fd, FIONBIO, &val);
+ }
#else
result = fcntl(fd, F_SETFL, O_NONBLOCK);
#endif
CREATE(session[fd], struct socket_data, 1);
- CREATE(session[fd]->rdata, char, rfifo_size);
- CREATE(session[fd]->wdata, char, wfifo_size);
+ CREATE_A(session[fd]->rdata, unsigned char, rfifo_size);
+ CREATE_A(session[fd]->wdata, unsigned char, wfifo_size);
session[fd]->max_rdata = rfifo_size;
session[fd]->max_wdata = wfifo_size;
@@ -211,6 +244,7 @@ static int connect_client(int listen_fd)
session[fd]->func_send = send_from_fifo;
session[fd]->func_parse = default_func_parse;
session[fd]->client_addr = client_address;
+ session[fd]->rdata_tick = tick_;
//printf("new_session : %d %d\n",fd,session[fd]->eof);
return fd;
@@ -221,9 +255,6 @@ int make_listen_port(int port)
struct sockaddr_in server_address;
int fd;
int result;
-#ifndef NSOCKET
- int yes = 1; // reuse fix
-#endif /* not NSOCKET */
fd = socket( AF_INET, SOCK_STREAM, 0 );
if(fd_max<=fd) fd_max=fd+1;
@@ -237,19 +268,11 @@ int make_listen_port(int port)
result = fcntl(fd, F_SETFL, O_NONBLOCK);
#endif
-#ifndef NSOCKET
- setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&yes,sizeof yes);
-#ifdef SO_REUSEPORT
- setsockopt(fd,SOL_SOCKET,SO_REUSEPORT,(char *)&yes,sizeof yes);
-#endif
- setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,(char *)&yes,sizeof yes);
-#else /* NSOCKET */
setsocketopts(fd);
-#endif /* NSOCKET */
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl( INADDR_ANY );
- server_address.sin_port = htons(port);
+ server_address.sin_port = htons((unsigned short)port);
result = bind(fd, (struct sockaddr*)&server_address, sizeof(server_address));
if( result == -1 ) {
@@ -276,16 +299,83 @@ int make_listen_port(int port)
return fd;
}
+int make_listen_bind(long ip,int port)
+{
+ struct sockaddr_in server_address;
+ int fd;
+ int result;
+
+ fd = socket( AF_INET, SOCK_STREAM, 0 );
+ if(fd_max<=fd) fd_max=fd+1;
+
+#ifdef _WIN32
+ {
+ unsigned long val = 1;
+ ioctlsocket(fd, FIONBIO, &val);
+ }
+#else
+ result = fcntl(fd, F_SETFL, O_NONBLOCK);
+#endif
+
+ setsocketopts(fd);
+
+ server_address.sin_family = AF_INET;
+ server_address.sin_addr.s_addr = ip;
+ server_address.sin_port = htons((unsigned short)port);
+
+#ifdef UPNP
+ if (upnp_dll) {
+ int localaddr = ntohl(addr_[0]);
+ unsigned char *natip = (unsigned char *)&localaddr;
+ char buf[16];
+ sprintf(buf, "%d.%d.%d.%d", natip[0], natip[1], natip[2], natip[3]);
+ //printf("natip=%d.%d.%d.%d\n", natip[0], natip[1], natip[2], natip[3]);
+ if (firewall_addport(argp, port))
+ printf ("Firewall port %d successfully opened\n", port);
+ if (natip[0] == 192 && natip[1] == 168) {
+ if (upnp_addport(argp, natip, port))
+ printf ("Upnp mappings successfull\n");
+ else printf ("Upnp mapping failed\n");
+ }
+ }
+#endif
+
+ result = bind(fd, (struct sockaddr*)&server_address, sizeof(server_address));
+ if( result == -1 ) {
+ perror("bind");
+ exit(1);
+ }
+ result = listen( fd, 5 );
+ if( result == -1 ) { /* error */
+ perror("listen");
+ exit(1);
+ }
+
+ FD_SET(fd, &readfds );
+
+ CREATE(session[fd], struct socket_data, 1);
+
+ if(session[fd]==NULL){
+ printf("out of memory : make_listen_bind\n");
+ exit(1);
+ }
+ memset(session[fd],0,sizeof(*session[fd]));
+ session[fd]->func_recv = connect_client;
+
+ return fd;
+}
+
// Console Reciever [Wizputer]
int console_recieve(int i) {
int n;
char *buf;
-
- CREATE(buf, char , 64);
-
+
+ CREATE_A(buf, char , 64);
+
memset(buf,0,sizeof(64));
n = read(0, buf , 64);
+
if ( n < 0 )
printf("Console input read error\n");
else
@@ -307,48 +397,36 @@ static int null_console_parse(char *buf)
// Console Input [Wizputer]
int start_console(void) {
FD_SET(0,&readfds);
-
+
CREATE(session[0], struct socket_data, 1);
if(session[0]==NULL){
printf("out of memory : start_console\n");
exit(1);
}
-
+
memset(session[0],0,sizeof(*session[0]));
-
+
session[0]->func_recv = console_recieve;
session[0]->func_console = default_console_parse;
-
+
return 0;
-}
-
+}
+
int make_connection(long ip,int port)
{
struct sockaddr_in server_address;
int fd;
int result;
-#ifndef NSOCKET
- int yes = 1; // reuse fix
-#endif /* not NSOCKET */
fd = socket( AF_INET, SOCK_STREAM, 0 );
-#ifndef NSOCKET
- if(fd_max<=fd) fd_max=fd+1;
- setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&yes,sizeof yes);
-#ifdef SO_REUSEPORT
- setsockopt(fd,SOL_SOCKET,SO_REUSEPORT,(char *)&yes,sizeof yes);
-#endif
- setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,(char *)&yes,sizeof yes);
-#else /* NSOCKET */
- if(fd_max<=fd)
+ if(fd_max<=fd)
fd_max=fd+1;
setsocketopts(fd);
-#endif /* NSOCKET */
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = ip;
- server_address.sin_port = htons(port);
+ server_address.sin_port = htons((unsigned short)port);
#ifdef _WIN32
{
@@ -364,31 +442,32 @@ int make_connection(long ip,int port)
FD_SET(fd,&readfds);
CREATE(session[fd], struct socket_data, 1);
- CREATE(session[fd]->rdata, char, rfifo_size);
- CREATE(session[fd]->wdata, char, wfifo_size);
+ CREATE_A(session[fd]->rdata, unsigned char, rfifo_size);
+ CREATE_A(session[fd]->wdata, unsigned char, wfifo_size);
session[fd]->max_rdata = rfifo_size;
session[fd]->max_wdata = wfifo_size;
session[fd]->func_recv = recv_to_fifo;
session[fd]->func_send = send_from_fifo;
session[fd]->func_parse = default_func_parse;
+ session[fd]->rdata_tick = tick_;
return fd;
}
int delete_session(int fd)
{
- if(fd<0 || fd>=FD_SETSIZE)
+ if(fd<=0 || fd>=FD_SETSIZE)
return -1;
FD_CLR(fd,&readfds);
if(session[fd]){
if(session[fd]->rdata)
- free(session[fd]->rdata);
+ aFree(session[fd]->rdata);
if(session[fd]->wdata)
- free(session[fd]->wdata);
+ aFree(session[fd]->wdata);
if(session[fd]->session_data)
- free(session[fd]->session_data);
- free(session[fd]);
+ aFree(session[fd]->session_data);
+ aFree(session[fd]);
}
session[fd]=NULL;
//printf("delete_session:%d\n",fd);
@@ -397,13 +476,16 @@ int delete_session(int fd)
int realloc_fifo(int fd,int rfifo_size,int wfifo_size)
{
- struct socket_data *s=session[fd];
+ struct socket_data *s;
+
+ if (fd <= 0) return 0;
+ s = session[fd];
if( s->max_rdata != rfifo_size && s->rdata_size < rfifo_size){
- RECREATE(s->rdata, char, rfifo_size);
+ RECREATE(s->rdata, unsigned char, rfifo_size);
s->max_rdata = rfifo_size;
}
if( s->max_wdata != wfifo_size && s->wdata_size < wfifo_size){
- RECREATE(s->wdata, char, wfifo_size);
+ RECREATE(s->wdata, unsigned char, wfifo_size);
s->max_wdata = wfifo_size;
}
return 0;
@@ -411,11 +493,12 @@ int realloc_fifo(int fd,int rfifo_size,int wfifo_size)
int WFIFOSET(int fd,int len)
{
- struct socket_data *s=session[fd];
-#ifdef NSOCKET
+ struct socket_data *s;
+
+ if (fd <= 0) return 0;
+ s = session[fd];
if (s == NULL || s->wdata == NULL)
return 0;
-#endif /* NSOCKET */
if( s->wdata_size+len+16384 > s->max_wdata ){
unsigned char *sin_addr = (unsigned char *)&s->client_addr.sin_addr;
realloc_fifo(fd,s->max_rdata, s->max_wdata <<1 );
@@ -423,10 +506,8 @@ int WFIFOSET(int fd,int len)
}
s->wdata_size=(s->wdata_size+(len)+2048 < s->max_wdata) ?
s->wdata_size+len : (printf("socket: %d wdata lost !!\n",fd),s->wdata_size);
-#ifdef NSOCKET
- if (s->wdata_size > (TCP_FRAME_LEN))
+ if (s->wdata_size > (TCP_FRAME_LEN))
send_from_fifo(fd);
-#endif /* NSOCKET */
return 0;
}
@@ -436,7 +517,10 @@ int do_sendrecv(int next)
struct timeval timeout;
int ret,i;
- rfd=readfds;
+ tick_ = time(0);
+
+ memcpy(&rfd, &readfds, sizeof(rfd));
+
FD_ZERO(&wfd);
for(i=0;i<fd_max;i++){
if(!session[i] && FD_ISSET(i,&readfds)){
@@ -460,13 +544,11 @@ int do_sendrecv(int next)
if(FD_ISSET(i,&wfd)){
//printf("write:%d\n",i);
if(session[i]->func_send)
- //send_from_fifo(i);
session[i]->func_send(i);
}
if(FD_ISSET(i,&rfd)){
//printf("read:%d\n",i);
if(session[i]->func_recv)
- //recv_to_fifo(i);
session[i]->func_recv(i);
}
}
@@ -479,6 +561,8 @@ int do_parsepacket(void)
for(i=0;i<fd_max;i++){
if(!session[i])
continue;
+ if ((session[i]->rdata_tick != 0) && ((tick_ - session[i]->rdata_tick) > stall_time_))
+ session[i]->eof = 1;
if(session[i]->rdata_size==0 && session[i]->eof==0)
continue;
if(session[i]->func_parse){
@@ -491,14 +575,306 @@ int do_parsepacket(void)
return 0;
}
-void do_socket(void)
+/* DDoS UŒ‚‘Îô */
+
+enum {
+ ACO_DENY_ALLOW=0,
+ ACO_ALLOW_DENY,
+ ACO_MUTUAL_FAILTURE,
+};
+
+struct _access_control {
+ unsigned int ip;
+ unsigned int mask;
+};
+
+static struct _access_control *access_allow;
+static struct _access_control *access_deny;
+static int access_order=ACO_DENY_ALLOW;
+static int access_allownum=0;
+static int access_denynum=0;
+static int access_debug=0;
+static int ddos_count = 10;
+static int ddos_interval = 3000;
+static int ddos_autoreset = 600*1000;
+
+struct _connect_history {
+ struct _connect_history *next;
+ struct _connect_history *prev;
+ int status;
+ int count;
+ unsigned int ip;
+ unsigned int tick;
+};
+static struct _connect_history *connect_history[0x10000];
+static int connect_check_(unsigned int ip);
+
+// Ú‘±‚Å‚«‚é‚©‚Ç‚¤‚©‚ÌŠm”F
+// false : Ú‘±OK
+// true : Ú‘±NG
+static int connect_check(unsigned int ip) {
+ int result = connect_check_(ip);
+ if(access_debug) {
+ printf("connect_check: Connection from %d.%d.%d.%d %s\n",
+ CONVIP(ip),result ? "allowed." : "denied!");
+ }
+ return result;
+}
+
+static int connect_check_(unsigned int ip) {
+ struct _connect_history *hist = connect_history[ip & 0xFFFF];
+ struct _connect_history *hist_new;
+ int i,is_allowip = 0,is_denyip = 0,connect_ok = 0;
+
+ // allow , deny ƒŠƒXƒg‚É“ü‚Á‚Ä‚¢‚é‚©Šm”F
+ for(i = 0;i < access_allownum; i++) {
+ if((ip & access_allow[i].mask) == (access_allow[i].ip & access_allow[i].mask)) {
+ if(access_debug) {
+ printf("connect_check: Found match from allow list:%d.%d.%d.%d IP:%d.%d.%d.%d Mask:%d.%d.%d.%d\n",
+ CONVIP(ip),
+ CONVIP(access_allow[i].ip),
+ CONVIP(access_allow[i].mask));
+ }
+ is_allowip = 1;
+ break;
+ }
+ }
+ for(i = 0;i < access_denynum; i++) {
+ if((ip & access_deny[i].mask) == (access_deny[i].ip & access_deny[i].mask)) {
+ if(access_debug) {
+ printf("connect_check: Found match from deny list:%d.%d.%d.%d IP:%d.%d.%d.%d Mask:%d.%d.%d.%d\n",
+ CONVIP(ip),
+ CONVIP(access_deny[i].ip),
+ CONVIP(access_deny[i].mask));
+ }
+ is_denyip = 1;
+ break;
+ }
+ }
+ // ƒRƒlƒNƒgo—ˆ‚é‚©‚Ç‚¤‚©Šm”F
+ // connect_ok
+ // 0 : –³ðŒ‚É‹‘”Û
+ // 1 : “c‘ã–Cƒ`ƒFƒbƒN‚ÌŒ‹‰ÊŽŸ‘æ
+ // 2 : –³ðŒ‚É‹–‰Â
+ switch(access_order) {
+ case ACO_DENY_ALLOW:
+ default:
+ if(is_allowip) {
+ connect_ok = 2;
+ } else if(is_denyip) {
+ connect_ok = 0;
+ } else {
+ connect_ok = 1;
+ }
+ break;
+ case ACO_ALLOW_DENY:
+ if(is_denyip) {
+ connect_ok = 0;
+ } else if(is_allowip) {
+ connect_ok = 2;
+ } else {
+ connect_ok = 1;
+ }
+ break;
+ case ACO_MUTUAL_FAILTURE:
+ if(is_allowip) {
+ connect_ok = 2;
+ } else {
+ connect_ok = 0;
+ }
+ break;
+ }
+
+ // Ú‘±—š—ð‚𒲂ׂé
+ while(hist) {
+ if(ip == hist->ip) {
+ // “¯‚¶IP”­Œ©
+ if(hist->status) {
+ // ban ƒtƒ‰ƒO‚ª—§‚Á‚Ä‚é
+ return (connect_ok == 2 ? 1 : 0);
+ } else if(DIFF_TICK(gettick(),hist->tick) < ddos_interval) {
+ // ddos_interval•bˆÈ“à‚ÉƒŠƒNƒGƒXƒg—L‚è
+ hist->tick = gettick();
+ if(hist->count++ >= ddos_count) {
+ // ddos UŒ‚‚ðŒŸo
+ hist->status = 1;
+ printf("connect_check: DDOS Attack detected from %d.%d.%d.%d!\n",
+ CONVIP(ip));
+ return (connect_ok == 2 ? 1 : 0);
+ } else {
+ return connect_ok;
+ }
+ } else {
+ // ddos_interval•bˆÈ“à‚ÉƒŠƒNƒGƒXƒg–³‚¢‚̂Ń^ƒCƒ}[ƒNƒŠƒA
+ hist->tick = gettick();
+ hist->count = 0;
+ return connect_ok;
+ }
+ }
+ hist = hist->next;
+ }
+ // IPƒŠƒXƒg‚É–³‚¢‚Ì‚ÅV‹Kì¬
+ hist_new = (struct _connect_history *) aCalloc(1,sizeof(struct _connect_history));
+ hist_new->ip = ip;
+ hist_new->tick = gettick();
+ if(connect_history[ip & 0xFFFF] != NULL) {
+ hist = connect_history[ip & 0xFFFF];
+ hist->prev = hist_new;
+ hist_new->next = hist;
+ }
+ connect_history[ip & 0xFFFF] = hist_new;
+ return connect_ok;
+}
+
+static int connect_check_clear(int tid,unsigned int tick,int id,int data) {
+ int i;
+ int clear = 0;
+ int list = 0;
+ struct _connect_history *hist , *hist2;
+ for(i = 0;i < 0x10000 ; i++) {
+ hist = connect_history[i];
+ while(hist) {
+ if(
+ (DIFF_TICK(tick,hist->tick) > ddos_interval * 3 && !hist->status) ||
+ (DIFF_TICK(tick,hist->tick) > ddos_autoreset && hist->status)
+ ) {
+ // clear data
+ hist2 = hist->next;
+ if(hist->prev) {
+ hist->prev->next = hist->next;
+ } else {
+ connect_history[i] = hist->next;
+ }
+ if(hist->next) {
+ hist->next->prev = hist->prev;
+ }
+ aFree(hist);
+ hist = hist2;
+ clear++;
+ } else {
+ hist = hist->next;
+ list++;
+ }
+ }
+ }
+ if(access_debug) {
+ printf("connect_check_clear: Cleared %d of %d from IP list.\n", clear, clear+list);
+ }
+ return list;
+}
+
+// IPƒ}ƒXƒNƒ`ƒFƒbƒN
+int access_ipmask(const char *str,struct _access_control* acc)
{
- FD_ZERO(&readfds);
+ unsigned int mask=0,i=0,m,ip, a0,a1,a2,a3;
+ if( !strcmp(str,"all") ) {
+ ip = 0;
+ mask = 0;
+ } else {
+ if( sscanf(str,"%d.%d.%d.%d%n",&a0,&a1,&a2,&a3,&i)!=4 || i==0) {
+ printf("access_ipmask: Unknown format %s!\n",str);
+ return 0;
+ }
+ ip = (a3 << 24) | (a2 << 16) | (a1 << 8) | a0;
+
+ if(sscanf(str+i,"/%d.%d.%d.%d",&a0,&a1,&a2,&a3)==4 ){
+ mask = (a3 << 24) | (a2 << 16) | (a1 << 8) | a0;
+ } else if(sscanf(str+i,"/%d",&m) == 1) {
+ for(i=0;i<m;i++) {
+ mask = (mask >> 1) | 0x80000000;
+ }
+ mask = ntohl(mask);
+ } else {
+ mask = 0xFFFFFFFF;
+ }
+ }
+ if(access_debug) {
+ printf("access_ipmask: Loaded IP:%d.%d.%d.%d mask:%d.%d.%d.%d\n",
+ CONVIP(ip), CONVIP(mask));
+ }
+ acc->ip = ip;
+ acc->mask = mask;
+ return 1;
+}
+
+int socket_config_read(const char *cfgName) {
+ int i;
+ char line[1024],w1[1024],w2[1024];
+ FILE *fp;
+
+ fp=fopen(cfgName, "r");
+ if(fp==NULL){
+ printf("File not found: %s\n", cfgName);
+ return 1;
+ }
+ while(fgets(line,1020,fp)){
+ if(line[0] == '/' && line[1] == '/')
+ continue;
+ i=sscanf(line,"%[^:]: %[^\r\n]",w1,w2);
+ if(i!=2)
+ continue;
+ if(strcmpi(w1,"stall_time")==0){
+ stall_time_ = atoi(w2);
+ } else if(strcmpi(w1,"enable_ip_rules")==0){
+ if(strcmpi(w2,"yes")==0)
+ ip_rules = 1;
+ else if(strcmpi(w2,"no")==0)
+ ip_rules = 0;
+ else ip_rules = atoi(w2);
+ } else if(strcmpi(w1,"order")==0){
+ access_order=atoi(w2);
+ if(strcmpi(w2,"deny,allow")==0) access_order=ACO_DENY_ALLOW;
+ if(strcmpi(w2,"allow,deny")==0) access_order=ACO_ALLOW_DENY;
+ if(strcmpi(w2,"mutual-failure")==0) access_order=ACO_MUTUAL_FAILTURE;
+ } else if(strcmpi(w1,"allow")==0){
+ access_allow = (struct _access_control *) aRealloc(access_allow,(access_allownum+1)*sizeof(struct _access_control));
+ if(access_ipmask(w2,&access_allow[access_allownum])) {
+ access_allownum++;
+ }
+ } else if(strcmpi(w1,"deny")==0){
+ access_deny = (struct _access_control *) aRealloc(access_deny,(access_denynum+1)*sizeof(struct _access_control));
+ if(access_ipmask(w2,&access_deny[access_denynum])) {
+ access_denynum++;
+ }
+ } else if(!strcmpi(w1,"ddos_interval")){
+ ddos_interval = atoi(w2);
+ } else if(!strcmpi(w1,"ddos_count")){
+ ddos_count = atoi(w2);
+ } else if(!strcmpi(w1,"ddos_autoreset")){
+ ddos_autoreset = atoi(w2);
+ } else if(!strcmpi(w1,"debug")){
+ if(strcmpi(w2,"yes")==0)
+ access_debug = 1;
+ else if(strcmpi(w2,"no")==0)
+ access_debug = 0;
+ else access_debug = atoi(w2);
+ #ifdef UPNP
+ } else if(!strcmpi(w1,"release_mappings")){
+ if(strcmpi(w2,"yes")==0)
+ release_mappings = 1;
+ else if(strcmpi(w2,"no")==0)
+ release_mappings = 0;
+ else release_mappings = atoi(w2);
+ } else if(!strcmpi(w1,"close_ports")){
+ if(strcmpi(w2,"yes")==0)
+ close_ports = 1;
+ else if(strcmpi(w2,"no")==0)
+ close_ports = 0;
+ else close_ports = atoi(w2);
+ #endif
+ } else if (strcmpi(w1, "import") == 0)
+ socket_config_read(w2);
+ }
+ fclose(fp);
+ return 0;
}
int RFIFOSKIP(int fd,int len)
{
- struct socket_data *s=session[fd];
+ struct socket_data *s;
+
+ if (fd <= 0) return 0;
+ s = session[fd];
if (s->rdata_size-s->rdata_pos-len<0) {
fprintf(stderr,"too many skip\n");
@@ -521,7 +897,7 @@ int Net_Init(void)
unsigned int i;
char fullhost[255];
struct hostent* hent;
-
+
/* Start up the windows networking */
WSADATA wsaData;
@@ -533,7 +909,7 @@ int Net_Init(void)
if(gethostname(fullhost, sizeof(fullhost)) == SOCKET_ERROR) {
printf("Ugg.. no hostname defined!\n");
return 0;
- }
+ }
// XXX This should look up the local IP addresses in the registry
// instead of calling gethostbyname. However, the way IP addresses
@@ -566,7 +942,7 @@ int Net_Init(void)
return 0;
}
- for(pos = 0; pos < ic.ifc_len;)
+ for(pos = 0; pos < ic.ifc_len;)
{
struct ifreq * ir = (struct ifreq *) (ic.ifc_buf + pos);
@@ -593,3 +969,101 @@ int Net_Init(void)
return(0);
}
+
+#ifdef UPNP
+// not implemented yet ^^;
+void do_init_upnp(void)
+{
+ int *_release_mappings;
+ int *_close_ports;
+
+ upnp_dll = DLL_OPEN ("upnp.dll");
+ if (!upnp_dll) {
+ printf ("Cannot open upnp.dll: %s\n", dlerror());
+ return;
+ }
+ DLL_SYM (upnp_init, upnp_dll, "do_init");
+ DLL_SYM (upnp_final, upnp_dll, "do_final");
+ DLL_SYM (firewall_addport, upnp_dll, "Firewall_AddPort");
+ DLL_SYM (upnp_addport, upnp_dll, "UPNP_AddPort");
+ if (!upnp_init || !upnp_final || !firewall_addport || !upnp_addport) {
+ printf ("Cannot load symbol: %s\n", dlerror());
+ DLL_CLOSE (upnp_dll);
+ upnp_dll = NULL;
+ return;
+ }
+
+ DLL_SYM (_release_mappings, upnp_dll, "release_mappings");
+ DLL_SYM (_close_ports, upnp_dll, "close_ports");
+ if (release_mappings && _release_mappings)
+ *_release_mappings = release_mappings;
+ if (close_ports && _close_ports)
+ *_close_ports = close_ports;
+
+ if (upnp_init() == 0) {
+ printf ("Error initialising upnp.dll, unloading...\n");
+ DLL_CLOSE (upnp_dll);
+ upnp_dll = NULL;
+ }
+ return;
+}
+#endif
+
+void do_final_socket(void)
+{
+ int i;
+ struct _connect_history *hist , *hist2;
+ for(i=0; i<fd_max; i++) {
+ if(session[i]) {
+ delete_session(i);
+ }
+ }
+ for(i=0; i<0x10000; i++) {
+ hist = connect_history[i];
+ while(hist) {
+ hist2 = hist->next;
+ aFree(hist);
+ hist = hist2;
+ }
+ }
+ if (access_allow)
+ aFree(access_allow);
+ if (access_deny)
+ aFree(access_deny);
+
+ // session[0] ‚̃_ƒ~[ƒf[ƒ^‚ðíœ
+ aFree(session[0]->rdata);
+ aFree(session[0]->wdata);
+ aFree(session[0]);
+
+#ifdef UPNP
+ if (upnp_dll) {
+ upnp_final();
+ DLL_CLOSE(upnp_dll);
+ }
+#endif
+}
+
+void do_socket(void)
+{
+ char *SOCKET_CONF_FILENAME = "conf/packet_athena.conf";
+
+ FD_ZERO(&readfds);
+
+ atexit(do_final_socket);
+ socket_config_read(SOCKET_CONF_FILENAME);
+
+ // session[0] ‚Ƀ_ƒ~[ƒf[ƒ^‚ðŠm•Û‚·‚é
+ CREATE(session[0], struct socket_data, 1);
+ CREATE_A(session[0]->rdata, unsigned char, rfifo_size);
+ CREATE_A(session[0]->wdata, unsigned char, wfifo_size);
+ session[0]->max_rdata = rfifo_size;
+ session[0]->max_wdata = wfifo_size;
+
+ // ‚Ƃ肠‚¦‚¸‚T•ª‚²‚Ƃɕs—v‚ȃf[ƒ^‚ð휂·‚é
+ add_timer_interval(gettick()+1000,connect_check_clear,0,0,300*1000);
+
+#ifdef UPNP
+ do_init_upnp();
+#endif
+}
diff --git a/src/common/socket.h b/src/common/socket.h
index e3ad0826a..37d41203e 100644
--- a/src/common/socket.h
+++ b/src/common/socket.h
@@ -5,24 +5,31 @@
#include <stdio.h>
-#ifdef _WIN32
+#ifdef __WIN32
#include <winsock.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif
+#include <time.h>
+#include "malloc.h"
+
+extern time_t tick_;
+extern time_t stall_time_;
// define declaration
+#define RFIFOSPACE(fd) (session[fd]->max_rdata-session[fd]->rdata_size)
#define RFIFOP(fd,pos) (session[fd]->rdata+session[fd]->rdata_pos+(pos))
-#define RFIFOB(fd,pos) (*(unsigned char*)(session[fd]->rdata+session[fd]->rdata_pos+(pos)))
-#define RFIFOW(fd,pos) (*(unsigned short*)(session[fd]->rdata+session[fd]->rdata_pos+(pos)))
-#define RFIFOL(fd,pos) (*(unsigned int*)(session[fd]->rdata+session[fd]->rdata_pos+(pos)))
-//#define RFIFOSKIP(fd,len) ((session[fd]->rdata_size-session[fd]->rdata_pos-(len)<0) ? (fprintf(stderr,"too many skip\n"),exit(1)) : (session[fd]->rdata_pos+=(len)))
-#define RFIFOREST(fd) (session[fd]->rdata_size-session[fd]->rdata_pos)
+// use function instead of macro.
+#define RFIFOB(fd,pos) (*(unsigned char*)RFIFOP(fd,pos))
+#define RFIFOW(fd,pos) (*(unsigned short*)RFIFOP(fd,pos))
+#define RFIFOL(fd,pos) (*(unsigned int*)RFIFOP(fd,pos))
+#define RFIFOREST(fd) (session[fd]->rdata_size-session[fd]->rdata_pos)
#define RFIFOFLUSH(fd) (memmove(session[fd]->rdata,RFIFOP(fd,0),RFIFOREST(fd)),session[fd]->rdata_size=RFIFOREST(fd),session[fd]->rdata_pos=0)
-#define RFIFOSPACE(fd) (session[fd]->max_rdata-session[fd]->rdata_size)
+//#define RFIFOSKIP(fd,len) ((session[fd]->rdata_size-session[fd]->rdata_pos-(len)<0) ? (fprintf(stderr,"too many skip\n"),exit(1)) : (session[fd]->rdata_pos+=(len)))
+
#define RBUFP(p,pos) (((unsigned char*)(p))+(pos))
#define RBUFB(p,pos) (*(unsigned char*)RBUFP((p),(pos)))
#define RBUFW(p,pos) (*(unsigned short*)RBUFP((p),(pos)))
@@ -30,9 +37,9 @@
#define WFIFOSPACE(fd) (session[fd]->max_wdata-session[fd]->wdata_size)
#define WFIFOP(fd,pos) (session[fd]->wdata+session[fd]->wdata_size+(pos))
-#define WFIFOB(fd,pos) (*(unsigned char*)(session[fd]->wdata+session[fd]->wdata_size+(pos)))
-#define WFIFOW(fd,pos) (*(unsigned short*)(session[fd]->wdata+session[fd]->wdata_size+(pos)))
-#define WFIFOL(fd,pos) (*(unsigned int*)(session[fd]->wdata+session[fd]->wdata_size+(pos)))
+#define WFIFOB(fd,pos) (*(unsigned char*)WFIFOP(fd,pos))
+#define WFIFOW(fd,pos) (*(unsigned short*)WFIFOP(fd,pos))
+#define WFIFOL(fd,pos) (*(unsigned int*)WFIFOP(fd,pos))
// use function instead of macro.
//#define WFIFOSET(fd,len) (session[fd]->wdata_size = (session[fd]->wdata_size+(len)+2048 < session[fd]->max_wdata) ? session[fd]->wdata_size+len : session[fd]->wdata_size)
#define WBUFP(p,pos) (((unsigned char*)(p))+(pos))
@@ -54,6 +61,7 @@ struct socket_data{
unsigned char *rdata,*wdata;
int max_rdata,max_wdata;
int rdata_size,wdata_size;
+ time_t rdata_tick;
int rdata_pos;
struct sockaddr_in client_addr;
int (*func_recv)(int);
@@ -80,6 +88,7 @@ extern int fd_max;
// Function prototype declaration
int make_listen_port(int);
+int make_listen_bind(long,int);
int make_connection(long,int);
int delete_session(int);
int realloc_fifo(int fd,int rfifo_size,int wfifo_size);
@@ -90,6 +99,9 @@ int do_sendrecv(int next);
int do_parsepacket(void);
void do_socket(void);
+extern void flush_fifos();
+extern void set_nonblocking(int fd, int yes);
+
int start_console(void);
void set_defaultparse(int (*defaultparse)(int));
diff --git a/src/char_sql/strlib.c b/src/common/strlib.c
index b113d96f5..2b130e76d 100644
--- a/src/char_sql/strlib.c
+++ b/src/common/strlib.c
@@ -4,18 +4,19 @@
#include "strlib.h"
#include "utils.h"
+#include "malloc.h"
//-----------------------------------------------
// string lib.
-unsigned char* jstrescape (unsigned char* pt) {
+char* jstrescape (char* pt) {
//copy from here
- unsigned char * ptr;
+ char *ptr;
int i =0, j=0;
-
+
//copy string to temporary
- CREATE(ptr, char, J_MAX_MALLOC_SIZE);
- strcpy (ptr,pt);
-
+ CREATE_A(ptr, char, J_MAX_MALLOC_SIZE);
+ strcpy(ptr,pt);
+
while (ptr[i] != '\0') {
switch (ptr[i]) {
case '\'':
@@ -31,14 +32,14 @@ unsigned char* jstrescape (unsigned char* pt) {
}
}
pt[j++] = '\0';
- free (ptr);
- return (unsigned char*) &pt[0];
+ aFree (ptr);
+ return &pt[0];
}
-unsigned char* jstrescapecpy (unsigned char* pt,unsigned char* spt) {
+char* jstrescapecpy (char* pt,char* spt) {
//copy from here
int i =0, j=0;
-
+
while (spt[i] != '\0') {
switch (spt[i]) {
case '\'':
@@ -54,12 +55,12 @@ unsigned char* jstrescapecpy (unsigned char* pt,unsigned char* spt) {
}
}
pt[j++] = '\0';
- return (unsigned char*) &pt[0];
+ return &pt[0];
}
-int jmemescapecpy (unsigned char* pt,unsigned char* spt, int size) {
+int jmemescapecpy (char* pt,char* spt, int size) {
//copy from here
int i =0, j=0;
-
+
while (i < size) {
switch (spt[i]) {
case '\'':
@@ -77,3 +78,21 @@ int jmemescapecpy (unsigned char* pt,unsigned char* spt, int size) {
// copy size is 0 ~ (j-1)
return j;
}
+
+//-----------------------------------------------------
+// Function to suppress control characters in a string.
+//-----------------------------------------------------
+//int remove_control_chars(char *str) {
+int remove_control_chars(unsigned char *str) {
+ int i;
+ int change = 0;
+
+ for(i = 0; str[i]; i++) {
+ if (str[i] < 32) {
+ str[i] = '_';
+ change = 1;
+ }
+ }
+
+ return change;
+}
diff --git a/src/login_sql/strlib.h b/src/common/strlib.h
index ddf29ab18..55920f823 100644
--- a/src/login_sql/strlib.h
+++ b/src/common/strlib.h
@@ -4,6 +4,10 @@
// String function library.
// code by Jioh L. Jung (ziozzang@4wish.net)
// This code is under license "BSD"
-unsigned char* jstrescape (unsigned char* pt);
-unsigned char* jstrescapecpy (unsigned char* pt,unsigned char* spt);
+char* jstrescape (char* pt);
+char* jstrescapecpy (char* pt,char* spt);
+int jmemescapecpy (char* pt,char* spt, int size);
+
+// custom functions
+int remove_control_chars(unsigned char *);
#endif
diff --git a/src/common/timer.c b/src/common/timer.c
index 97c162e7f..6a740d47a 100644
--- a/src/common/timer.c
+++ b/src/common/timer.c
@@ -1,37 +1,34 @@
-// $Id: timer.c,v 1.1.1.1 2004/09/10 17:44:49 MagicalTux Exp $
+// $Id: timer.c,v 1.1.1.1 2004/09/10 17:44:49 Yor Exp $
// original : core.c 2003/02/26 18:03:12 Rev 1.7
+//#include <config.h>
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
-#ifdef _WIN32
-#include <winsock.h>
+#ifdef __WIN32
+#define __USE_W32_SOCKETS
+#include <windows.h>
#else
#include <sys/socket.h>
#include <sys/time.h>
#endif
#include "timer.h"
-#include "utils.h"
+#include "malloc.h"
#ifdef MEMWATCH
#include "memwatch.h"
#endif
-// If the server shows no reaction when processing thousands of monsters
-
-// or connected by many clients, please increase TIMER_MIN_INTERVEL.
-
-#define TIMER_MIN_INTERVEL 50
-
static struct TimerData* timer_data;
-static int timer_data_max,timer_data_num;
+static int timer_data_max, timer_data_num;
static int* free_timer_list;
static int free_timer_list_max, free_timer_list_pos;
-static int timer_heap_max=0; //fixed Shinomori from eA forums
+static int timer_heap_num = 0, timer_heap_max = 0;
static int* timer_heap = NULL;
// for debug
@@ -42,38 +39,37 @@ struct timer_func_list {
};
static struct timer_func_list* tfl_root;
-#if defined(_WIN32)
-void gettimeofday(struct timeval *t, struct timezone *dummy)
-{
- DWORD millisec = GetTickCount();
+#ifdef __WIN32
+/* Modified struct timezone to void - we pass NULL anyway */
+void gettimeofday(struct timeval *t, void *dummy) {
+ DWORD millisec = GetTickCount();
- t->tv_sec = (int) (millisec / 1000);
- t->tv_usec = (millisec % 1000) * 1000;
+ t->tv_sec = (int) (millisec / 1000);
+ t->tv_usec = (millisec % 1000) * 1000;
}
-
#endif
-
//
-int add_timer_func_list(int (*func)(int,unsigned int,int,int),char* name)
-{
+int add_timer_func_list(int (*func)(int,unsigned int,int,int), char* name) {
struct timer_func_list* tfl;
- CREATE(tfl, struct timer_func_list, 1);
- CREATE(tfl->name, char, strlen(name) + 1);
+ //CALLOC(tfl, struct timer_func_list, 1);
+ tfl = (struct timer_func_list*) aCalloc( sizeof(struct timer_func_list) , 1);
+ //MALLOC(tfl->name, char, strlen(name) + 1);
+ tfl->name = (char *) aMalloc( strlen(name) + 1 );
tfl->next = tfl_root;
tfl->func = func;
- strcpy(tfl->name,name);
+ strcpy(tfl->name, name);
tfl_root = tfl;
return 0;
}
-char* search_timer_func_list(int (*func)(int,unsigned int,int,int))
-{
+char* search_timer_func_list(int (*func)(int,unsigned int,int,int)) {
struct timer_func_list* tfl;
- for(tfl = tfl_root;tfl;tfl = tfl->next) {
+
+ for(tfl = tfl_root; tfl; tfl = tfl->next) {
if (func == tfl->func)
return tfl->name;
}
@@ -85,19 +81,21 @@ char* search_timer_func_list(int (*func)(int,unsigned int,int,int))
*----------------------------*/
static unsigned int gettick_cache;
static int gettick_count;
-unsigned int gettick_nocache(void)
-{
+
+unsigned int gettick_nocache(void) {
struct timeval tval;
- gettimeofday(&tval,NULL);
+
+ gettimeofday(&tval, NULL);
gettick_count = 256;
- return gettick_cache = tval.tv_sec * 1000 + tval.tv_usec/1000;
+
+ return gettick_cache = tval.tv_sec * 1000 + tval.tv_usec / 1000;
}
-unsigned int gettick(void)
-{
+unsigned int gettick(void) {
gettick_count--;
- if (gettick_count<0)
+ if (gettick_count < 0)
return gettick_nocache();
+
return gettick_cache;
}
@@ -105,71 +103,66 @@ unsigned int gettick(void)
* CORE : Timer Heap
*--------------------------------------
*/
-static void push_timer_heap(int index)
-{
- int i, h;
-
- if (timer_heap == NULL || timer_heap[0] + 1 >= timer_heap_max) {
- int first = timer_heap == NULL;
-
- timer_heap_max += 256;
- RECREATE(timer_heap, int, timer_heap_max);
- memset(timer_heap + (timer_heap_max - 256), 0, sizeof(int) * 256);
- if (first)
- timer_heap[0] = 0;
- }
-
- timer_heap[0]++;
-
- for (h = timer_heap[0]-1, i = (h - 1) / 2;
- h > 0 && DIFF_TICK(timer_data[index].tick,
- timer_data[timer_heap[i + 1]].tick) < 0;
- i = (h - 1) / 2) {
- timer_heap[h + 1] = timer_heap[i + 1];
- h = i;
- }
- timer_heap[h + 1] = index;
-}
-
-static int top_timer_heap()
-{
- if (timer_heap == NULL || timer_heap[0] <= 0)
- return -1;
-
- return timer_heap[1];
-}
-
-static int pop_timer_heap()
-{
- int i,h,k;
- int ret,last;
-
- if (timer_heap == NULL || timer_heap[0] <= 0)
- return -1;
- ret = timer_heap[1];
- last = timer_heap[timer_heap[0]];
- timer_heap[0]--;
-
- for(h = 0,k = 2;k<timer_heap[0];k = k * 2 + 2) {
- if (DIFF_TICK(timer_data[timer_heap[k + 1]].tick , timer_data[timer_heap[k]].tick)>0)
- k--;
- timer_heap[h + 1] = timer_heap[k + 1], h = k;
+static void push_timer_heap(int index) {
+ int i, j;
+ int min, max, pivot; // for sorting
+
+ // check number of element
+ if (timer_heap_num >= timer_heap_max) {
+ if (timer_heap_max == 0) {
+ timer_heap_max = 256;
+ //CALLOC(timer_heap, int, 256);
+ timer_heap = (int *) aCalloc( sizeof(int) , 256);
+ } else {
+ timer_heap_max += 256;
+ //REALLOC(timer_heap, int, timer_heap_max);
+ timer_heap = (int *) aRealloc( timer_heap, sizeof(int) * timer_heap_max);
+ memset(timer_heap + (timer_heap_max - 256), 0, sizeof(int) * 256);
+ }
}
- if (k == timer_heap[0])
- timer_heap[h + 1] = timer_heap[k], h = k-1;
- for(i = (h-1)/2;
- h>0 && DIFF_TICK(timer_data[timer_heap[i + 1]].tick , timer_data[last].tick)>0;
- i = (h-1)/2) {
- timer_heap[h + 1] = timer_heap[i + 1],h = i;
+ // do a sorting from higher to lower
+ j = timer_data[index].tick; // speed up
+ // with less than 4 values, it's speeder to use simple loop
+ if (timer_heap_num < 4) {
+ for(i = timer_heap_num; i > 0; i--)
+ if (j < timer_data[timer_heap[i - 1]].tick)
+ break;
+ else
+ timer_heap[i] = timer_heap[i - 1];
+ timer_heap[i] = index;
+ // searching by dichotomie
+ } else {
+ // if lower actual item is higher than new
+ if (j < timer_data[timer_heap[timer_heap_num - 1]].tick)
+ timer_heap[timer_heap_num] = index;
+ else {
+ // searching position
+ min = 0;
+ max = timer_heap_num - 1;
+ while (min < max) {
+ pivot = (min + max) / 2;
+ if (j < timer_data[timer_heap[pivot]].tick)
+ min = pivot + 1;
+ else
+ max = pivot;
+ }
+ // move elements - do loop if there are a little number of elements to move
+ if (timer_heap_num - min < 5) {
+ for(i = timer_heap_num; i > min; i--)
+ timer_heap[i] = timer_heap[i - 1];
+ // move elements - else use memmove (speeder for a lot of elements)
+ } else
+ memmove(&timer_heap[min + 1], &timer_heap[min], sizeof(int) * (timer_heap_num - min));
+ // save new element
+ timer_heap[min] = index;
+ }
}
- timer_heap[h + 1] = last;
- return ret;
+ timer_heap_num++;
}
-int add_timer(unsigned int tick,int (*func)(int,unsigned int,int,int),int id,int data)
-{
+int add_timer(unsigned int tick,int (*func)(int,unsigned int,int,int),int id,int data) {
struct TimerData* td;
int i;
@@ -180,24 +173,18 @@ int add_timer(unsigned int tick,int (*func)(int,unsigned int,int,int),int id,int
} else
i = timer_data_num;
if (i >= timer_data_num)
- for (i = timer_data_num;i<timer_data_max && timer_data[i].type; i++);
+ for (i = timer_data_num; i < timer_data_max && timer_data[i].type; i++);
if (i >= timer_data_num && i >= timer_data_max) {
- int j;
if (timer_data_max == 0) {
timer_data_max = 256;
- CREATE(timer_data, struct TimerData, timer_data_max);
+ //CALLOC(timer_data, struct TimerData, timer_data_max);
+ timer_data = (struct TimerData*) aCalloc( sizeof(struct TimerData) , timer_data_max);
} else {
timer_data_max += 256;
- RECREATE(timer_data, struct TimerData, timer_data_max);
- if (timer_data == NULL) {
- printf("out of memory : add_timer timer_data\n");
- exit(1);
- }
- memset(timer_data + (timer_data_max - 256), 0,
- sizeof(struct TimerData) * 256);
+ //REALLOC(timer_data, struct TimerData, timer_data_max);
+ timer_data = (struct TimerData *) aRealloc( timer_data, sizeof(struct TimerData) * timer_data_max);
+ memset(timer_data + (timer_data_max - 256), 0, sizeof(struct TimerData) * 256);
}
- for(j = timer_data_max-256;j<timer_data_max; j++)
- timer_data[j].type = 0;
}
td = &timer_data[i];
td->tick = tick;
@@ -209,88 +196,79 @@ int add_timer(unsigned int tick,int (*func)(int,unsigned int,int,int),int id,int
push_timer_heap(i);
if (i >= timer_data_num)
timer_data_num = i + 1;
+
return i;
}
-int add_timer_interval(unsigned int tick,int (*func)(int,unsigned int,int,int),int id,int data,int interval)
-{
+int add_timer_interval(unsigned int tick,int (*func)(int,unsigned int,int,int),int id,int data,int interval) {
int tid;
+
tid = add_timer(tick,func,id,data);
timer_data[tid].type = TIMER_INTERVAL;
timer_data[tid].interval = interval;
+
return tid;
}
-int delete_timer(int id,int (*func)(int,unsigned int,int,int))
-{
+int delete_timer(int id,int (*func)(int,unsigned int,int,int)) {
if (id <= 0 || id >= timer_data_num) {
printf("delete_timer error : no such timer %d\n", id);
return -1;
}
if (timer_data[id].func != func) {
printf("delete_timer error : function dismatch %08x(%s) != %08x(%s)\n",
- (int)timer_data[id].func,
- search_timer_func_list(timer_data[id].func),
- (int)func,
- search_timer_func_list(func));
+ (int)timer_data[id].func, search_timer_func_list(timer_data[id].func),
+ (int)func, search_timer_func_list(func));
return -2;
}
// ‚»‚Ì‚¤‚¿Á‚¦‚é‚ɂ܂©‚¹‚é
timer_data[id].func = NULL;
timer_data[id].type = TIMER_ONCE_AUTODEL;
- timer_data[id].tick -= 60 * 60 * 1000;
+// timer_data[id].tick -= 60 * 60 * 1000;
+
return 0;
}
-int addtick_timer(int tid,unsigned int tick)
-{
+int addtick_timer(int tid,unsigned int tick) {
return timer_data[tid].tick += tick;
}
-struct TimerData* get_timer(int tid)
-{
+
+struct TimerData* get_timer(int tid) {
return &timer_data[tid];
}
+int do_timer(unsigned int tick) {
+ int i, nextmin = 1000;
-int do_timer(unsigned int tick)
-{
- int i,nextmin = 1000;
-
-#if 0
- static int disp_tick = 0;
- if (DIFF_TICK(disp_tick,tick)<-5000 || DIFF_TICK(disp_tick,tick)>5000) {
- printf("timer %d(%d + %d)\n",timer_data_num,timer_heap[0],free_timer_list_pos);
- disp_tick = tick;
- }
-#endif
-
- while((i = top_timer_heap()) >= 0) {
- if (DIFF_TICK(timer_data[i].tick , tick)>0) {
- nextmin = DIFF_TICK(timer_data[i].tick , tick);
+ while(timer_heap_num) {
+ i = timer_heap[timer_heap_num - 1]; // next shorter element
+ if (DIFF_TICK(timer_data[i].tick, tick) > 0) {
+ nextmin = DIFF_TICK(timer_data[i].tick, tick);
break;
}
- pop_timer_heap();
+ if (timer_heap_num > 0) // suppress the actual element from the table
+ timer_heap_num--;
timer_data[i].type |= TIMER_REMOVE_HEAP;
if (timer_data[i].func) {
- if (DIFF_TICK(timer_data[i].tick , tick) < -1000) {
+ if (DIFF_TICK(timer_data[i].tick, tick) < -1000) {
// 1•bˆÈã‚̑啂Ȓx‰„‚ª”­¶‚µ‚Ä‚¢‚é‚Ì‚ÅA
// timerˆ—ƒ^ƒCƒ~ƒ“ƒO‚ðŒ»Ý’l‚Æ‚·‚鎖‚Å
// ŒÄ‚Ño‚µŽžƒ^ƒCƒ~ƒ“ƒO(ˆø”‚Ìtick)‘Š‘Î‚Åˆ—‚µ‚Ä‚é
// timerŠÖ”‚ÌŽŸ‰ñˆ—ƒ^ƒCƒ~ƒ“ƒO‚ð’x‚点‚é
- timer_data[i].func(i,tick,timer_data[i].id,timer_data[i].data);
+ timer_data[i].func(i, tick, timer_data[i].id, timer_data[i].data);
} else {
- timer_data[i].func(i,timer_data[i].tick,timer_data[i].id,timer_data[i].data);
+ timer_data[i].func(i, timer_data[i].tick, timer_data[i].id, timer_data[i].data);
}
}
- if (timer_data[i].type&TIMER_REMOVE_HEAP) {
+ if (timer_data[i].type & TIMER_REMOVE_HEAP) {
switch(timer_data[i].type & ~TIMER_REMOVE_HEAP) {
case TIMER_ONCE_AUTODEL:
timer_data[i].type = 0;
if (free_timer_list_pos >= free_timer_list_max) {
free_timer_list_max += 256;
- RECREATE(free_timer_list, int, free_timer_list_max);
- memset(free_timer_list + (free_timer_list_max - 256), 0,
- 256 * sizeof(free_timer_list[0]));
+ //REALLOC(free_timer_list, int, free_timer_list_max);
+ free_timer_list = (int *) aRealloc(free_timer_list, sizeof(int) * free_timer_list_max);
+ memset(free_timer_list + (free_timer_list_max - 256), 0, 256 * sizeof(int));
}
free_timer_list[free_timer_list_pos++] = i;
break;
@@ -307,13 +285,31 @@ int do_timer(unsigned int tick)
}
}
- if(nextmin < TIMER_MIN_INTERVEL)
+ if (nextmin < 10)
+ nextmin = 10;
- nextmin = TIMER_MIN_INTERVEL;
return nextmin;
}
-void timer_final()
-{
- free(timer_data);
+void timer_final() {
+ struct timer_func_list* tfl = tfl_root, *tfl2;
+
+// while (tfl) {
+// tfl2 = tfl;
+// aFree(tfl->name);
+// aFree(tfl);
+// tfl = tfl2->next; // access on already freed memory
+// }
+
+ while (tfl) {
+ tfl2 = tfl->next; // copy next pointer
+ aFree(tfl->name); // free structures
+ aFree(tfl);
+ tfl = tfl2; // use copied pointer for next cycle
+ }
+
+ if (timer_data) aFree(timer_data);
+ if (timer_heap) aFree(timer_heap);
+ if (free_timer_list) aFree(free_timer_list);
}
+
diff --git a/src/common/timer.h b/src/common/timer.h
index f6fc5c84d..81086cb70 100644
--- a/src/common/timer.h
+++ b/src/common/timer.h
@@ -3,6 +3,12 @@
#ifndef _TIMER_H_
#define _TIMER_H_
+#ifdef __WIN32
+/* We need winsock lib to have timeval struct - windows is weirdo */
+#define __USE_W32_SOCKETS
+#include <windows.h>
+#endif
+
#define BASE_TICK 5
#define TIMER_ONCE_AUTODEL 1
@@ -25,6 +31,10 @@ struct TimerData {
// Function prototype declaration
+#ifdef __WIN32
+void gettimeofday(struct timeval *t, void *dummy);
+#endif
+
unsigned int gettick_nocache(void);
unsigned int gettick(void);
@@ -40,6 +50,6 @@ int do_timer(unsigned int tick);
int add_timer_func_list(int (*)(int,unsigned int,int,int),char*);
char* search_timer_func_list(int (*)(int,unsigned int,int,int));
-extern void timer_final();
+void timer_final();
#endif // _TIMER_H_
diff --git a/src/common/utils.c b/src/common/utils.c
index 2a09f773e..732b1d366 100644
--- a/src/common/utils.c
+++ b/src/common/utils.c
@@ -1,8 +1,10 @@
#include <string.h>
#include "utils.h"
#include <stdio.h>
-#include <stdlib.h>
#include <stdarg.h>
+#include <stdlib.h>
+#include "malloc.h"
+#include "mmo.h"
void dump(unsigned char *buffer, int num)
{
@@ -111,7 +113,7 @@ void str_lower(char *name)
// Allocate a StringBuf [MouseJstr]
struct StringBuf * StringBuf_Malloc()
{
- struct StringBuf * ret = (struct StringBuf *) malloc(sizeof(struct StringBuf));
+ struct StringBuf * ret = (struct StringBuf *) aMallocA(sizeof(struct StringBuf));
StringBuf_Init(ret);
return ret;
}
@@ -119,7 +121,7 @@ struct StringBuf * StringBuf_Malloc()
// Initialize a previously allocated StringBuf [MouseJstr]
void StringBuf_Init(struct StringBuf * sbuf) {
sbuf->max_ = 1024;
- sbuf->ptr_ = sbuf->buf_ = (char *) malloc(sbuf->max_ + 1);
+ sbuf->ptr_ = sbuf->buf_ = (char *) aMallocA(sbuf->max_ + 1);
}
// printf into a StringBuf, moving the pointer [MouseJstr]
@@ -142,7 +144,7 @@ int StringBuf_Printf(struct StringBuf *sbuf,const char *fmt,...)
/* Else try again with more space. */
sbuf->max_ *= 2; // twice the old size
off = sbuf->ptr_ - sbuf->buf_;
- sbuf->buf_ = (char *) realloc(sbuf->buf_, sbuf->max_ + 1);
+ sbuf->buf_ = (char *) aRealloc(sbuf->buf_, sbuf->max_ + 1);
sbuf->ptr_ = sbuf->buf_ + off;
}
}
@@ -156,7 +158,7 @@ int StringBuf_Append(struct StringBuf *buf1,const struct StringBuf *buf2)
if (size2 >= buf1_avail) {
int off = buf1->ptr_ - buf1->buf_;
buf1->max_ += size2;
- buf1->buf_ = (char *) realloc(buf1->buf_, buf1->max_ + 1);
+ buf1->buf_ = (char *) aRealloc(buf1->buf_, buf1->max_ + 1);
buf1->ptr_ = buf1->buf_ + off;
}
@@ -168,7 +170,7 @@ int StringBuf_Append(struct StringBuf *buf1,const struct StringBuf *buf2)
// Destroy a StringBuf [MouseJstr]
void StringBuf_Destroy(struct StringBuf *sbuf)
{
- free(sbuf->buf_);
+ aFree(sbuf->buf_);
sbuf->ptr_ = sbuf->buf_ = 0;
}
@@ -176,7 +178,7 @@ void StringBuf_Destroy(struct StringBuf *sbuf)
void StringBuf_Free(struct StringBuf *sbuf)
{
StringBuf_Destroy(sbuf);
- free(sbuf);
+ aFree(sbuf);
}
// Return the built string from the StringBuf [MouseJstr]
diff --git a/src/common/utils.h b/src/common/utils.h
index 248bcd867..63c3f21ec 100644
--- a/src/common/utils.h
+++ b/src/common/utils.h
@@ -1,5 +1,6 @@
-#ifndef UTILS_H
-#define UTILS_H
+#ifndef COMMON_UTILS_H
+#define COMMON_UTILS_H
+
#ifndef NULL
#define NULL (void *)0
@@ -20,16 +21,23 @@
#endif
-void dump(unsigned char *buffer, int num);
+ void dump(unsigned char *buffer, int num);
+
#define CREATE(result, type, number) do {\
if ((number) * sizeof(type) <= 0) \
printf("SYSERR: Zero bytes or less requested at %s:%d.\n", __FILE__, __LINE__); \
- if (!((result) = (type *) calloc ((number), sizeof(type)))) \
+ if (!((result) = (type *) aCalloc ((number), sizeof(type)))) \
+ { perror("SYSERR: malloc failure"); abort(); } } while(0)
+
+#define CREATE_A(result, type, number) do {\
+ if ((number) * sizeof(type) <= 0) \
+ printf("SYSERR: Zero bytes or less requested at %s:%d.\n", __FILE__, __LINE__); \
+ if (!((result) = (type *) aCallocA ((number), sizeof(type)))) \
{ perror("SYSERR: malloc failure"); abort(); } } while(0)
#define RECREATE(result,type,number) do {\
- if (!((result) = (type *) realloc ((result), sizeof(type) * (number))))\
+ if (!((result) = (type *) aRealloc ((result), sizeof(type) * (number))))\
{ printf("SYSERR: realloc failure"); abort(); } } while(0)
struct StringBuf {
diff --git a/src/ladmin/GNUmakefile b/src/ladmin/GNUmakefile
deleted file mode 100644
index 879edaeea..000000000
--- a/src/ladmin/GNUmakefile
+++ /dev/null
@@ -1,14 +0,0 @@
-all: ladmin
-txt: ladmin
-sql: ladmin
-
-COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o ../common/malloc.o ../common/showmsg.o
-COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/db.h ../common/malloc.h ../common/showmsg.h
-
-ladmin: ladmin.o md5calc.o $(COMMON_OBJ)
- $(CC) -o ../../$@ ladmin.o md5calc.o $(COMMON_OBJ)
-ladmin.o: ladmin.c ladmin.h md5calc.h $(COMMON_H)
-md5calc.o: md5calc.c md5calc.h
-
-clean:
- rm -f *.o ../../ladmin
diff --git a/src/ladmin/Makefile b/src/ladmin/Makefile
index 879edaeea..20722350b 100644
--- a/src/ladmin/Makefile
+++ b/src/ladmin/Makefile
@@ -2,11 +2,11 @@ all: ladmin
txt: ladmin
sql: ladmin
-COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o ../common/malloc.o ../common/showmsg.o
-COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/db.h ../common/malloc.h ../common/showmsg.h
+COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o ../common/obj/db.o ../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/strlib.o
+COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/db.h ../common/malloc.h ../common/showmsg.h ../common/strlib.h
ladmin: ladmin.o md5calc.o $(COMMON_OBJ)
- $(CC) -o ../../$@ ladmin.o md5calc.o $(COMMON_OBJ)
+ $(CC) -o ../../$@ ladmin.o md5calc.o $(COMMON_OBJ) $(LIB_S)
ladmin.o: ladmin.c ladmin.h md5calc.h $(COMMON_H)
md5calc.o: md5calc.c md5calc.h
diff --git a/src/ladmin/ladmin.c b/src/ladmin/ladmin.c
index 497f3bdab..432a78a95 100644
--- a/src/ladmin/ladmin.c
+++ b/src/ladmin/ladmin.c
@@ -6,27 +6,42 @@
///////////////////////////////////////////////////////////////////////////
#include <sys/types.h>
+#include <time.h>
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <winsock2.h>
+void Gettimeofday(struct timeval *timenow)
+{
+ time_t t;
+ t = clock();
+ timenow->tv_usec = t;
+ timenow->tv_sec = t / CLK_TCK;
+ return;
+}
+#define gettimeofday(timenow, dummy) Gettimeofday(timenow)
+#else
#include <sys/socket.h>
-#include <stdio.h>
-#include <stdlib.h>
#include <netinet/in.h>
#include <sys/time.h> // gettimeofday
-#include <time.h>
#include <sys/ioctl.h>
#include <unistd.h> // close
+#include <arpa/inet.h> // inet_addr
+#include <netdb.h> // gethostbyname
+#endif
+#include <stdio.h>
+#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h> // str*
-#include <arpa/inet.h> // inet_addr
-#include <netdb.h> // gethostbyname
#include <stdarg.h> // valist
#include <ctype.h> // tolower
-#include "core.h"
-#include "socket.h"
+#include "../common/strlib.h"
+#include "../common/core.h"
+#include "../common/socket.h"
#include "ladmin.h"
-#include "version.h"
-#include "mmo.h"
+#include "../common/version.h"
+#include "../common/mmo.h"
#ifdef PASSWORDENC
#include "md5calc.h"
@@ -266,7 +281,7 @@ int ladmin_log(char *fmt, ...) {
fprintf(logfp, RETCODE);
else {
gettimeofday(&tv, NULL);
- strftime(tmpstr, 24, date_format, localtime(&(tv.tv_sec)));
+ strftime(tmpstr, 24, date_format, localtime((const time_t*)&(tv.tv_sec)));
sprintf(tmpstr + strlen(tmpstr), ".%03d: %s", (int)tv.tv_usec / 1000, fmt);
vfprintf(logfp, tmpstr, ap);
}
@@ -277,23 +292,6 @@ int ladmin_log(char *fmt, ...) {
return 0;
}
-//-----------------------------------------------------
-// Function to suppress control characters in a string.
-//-----------------------------------------------------
-int remove_control_chars(unsigned char *str) {
- int i;
- int change = 0;
-
- for(i = 0; str[i]; i++) {
- if (str[i] < 32) {
- str[i] = '_';
- change = 1;
- }
- }
-
- return change;
-}
-
//---------------------------------------------
// Function to return ordonal text of a number.
//---------------------------------------------
@@ -367,9 +365,9 @@ int verify_accountname(char* account_name) {
//---------------------------------------------------
// E-mail check: return 0 (not correct) or 1 (valid).
//---------------------------------------------------
-int e_mail_check(unsigned char *email) {
+int e_mail_check(char *email) {
char ch;
- unsigned char* last_arobas;
+ char* last_arobas;
// athena limits
if (strlen(email) < 3 || strlen(email) > 39)
@@ -3252,7 +3250,7 @@ int parse_fromlogin(int fd) {
}
// printf("parse_fromlogin : %d %d %d\n", fd, RFIFOREST(fd), RFIFOW(fd,0));
- sd = session[fd]->session_data;
+ sd = (struct char_session_data*)session[fd]->session_data;
while(RFIFOREST(fd) >= 2) {
switch(RFIFOW(fd,0)) {
@@ -3302,11 +3300,11 @@ int parse_fromlogin(int fd) {
memcpy(md5key, RFIFOP(fd,4), RFIFOW(fd,2) - 4);
md5key[sizeof(md5key)-1] = '0';
if (passenc == 1) {
- strncpy(md5str, RFIFOP(fd,4), RFIFOW(fd,2) - 4);
+ strncpy(md5str, (const char*)RFIFOP(fd,4), RFIFOW(fd,2) - 4);
strcat(md5str, loginserveradminpassword);
} else if (passenc == 2) {
strncpy(md5str, loginserveradminpassword, sizeof(loginserveradminpassword));
- strcat(md5str, RFIFOP(fd,4));
+ strcat(md5str, (const char*)RFIFOP(fd,4));
}
MD5_String2binary(md5str, md5bin);
WFIFOW(login_fd,0) = 0x7918; // Request for administation login (encrypted password)
@@ -3801,7 +3799,7 @@ int parse_fromlogin(int fd) {
case 0x7947: // answer of an account name search
if (RFIFOREST(fd) < 30)
return 0;
- if (strcmp(RFIFOP(fd,6), "") == 0) {
+ if (strcmp((const char*)RFIFOP(fd,6), "") == 0) {
if (defaultlanguage == 'F') {
printf("Impossible de trouver le nom du compte [%d]. Le compte n'existe pas.\n", RFIFOL(fd,2));
ladmin_log("Impossible de trouver le nom du compte [%d]. Le compte n'existe pas." RETCODE, RFIFOL(fd,2));
@@ -4018,7 +4016,7 @@ int parse_fromlogin(int fd) {
connect_until_time = (time_t)RFIFOL(fd,140);
ban_until_time = (time_t)RFIFOL(fd,144);
memset(memo, '\0', sizeof(memo));
- strncpy(memo, RFIFOP(fd,150), RFIFOW(fd,148));
+ strncpy(memo, (const char*)RFIFOP(fd,150), RFIFOW(fd,148));
if (RFIFOL(fd,2) == -1) {
if (defaultlanguage == 'F') {
printf("Impossible de trouver le compte [%s]. Le compte n'existe pas.\n", parameters);
@@ -4258,8 +4256,8 @@ int ladmin_config_read(const char *cfgName) {
line[sizeof(line)-1] = '\0';
if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2) {
- remove_control_chars(w1);
- remove_control_chars(w2);
+ remove_control_chars((unsigned char *) w1);
+ remove_control_chars((unsigned char *) w2);
if(strcmpi(w1,"login_ip")==0){
struct hostent *h = gethostbyname (w2);
diff --git a/src/ladmin/md5calc.c b/src/ladmin/md5calc.c
index 7b9a9a2c6..c6c958583 100644
--- a/src/ladmin/md5calc.c
+++ b/src/ladmin/md5calc.c
@@ -96,7 +96,7 @@ static void MD5_Round_Calculate(const unsigned char *block,
//Save A as AA, B as BB, C as CC, and and D as DD (saving of A, B, C, and D)
unsigned int A=*A2, B=*B2, C=*C2, D=*D2;
unsigned int AA = A,BB = B,CC = C,DD = D;
-
+
//It is a large region variable reluctantly because of calculation of a round. . . for Round1...4
pX = X;
@@ -187,7 +187,7 @@ void MD5_String2binary(const char * string, char * output)
memset(padding_message+copy_len, 0, 64 - copy_len); //It buries by 0 until it becomes extended bit length.
padding_message[copy_len] |= 0x80; //The next of a message is 1.
- //1-4
+ //1-4
//If 56 bytes or more (less than 64 bytes) of remainder becomes, it will calculate by extending to 64 bytes.
if (56 <= copy_len) {
MD5_Round_Calculate(padding_message, A,B,C,D);
@@ -226,7 +226,7 @@ void MD5_String(const char * string, char * output)
{
unsigned char digest[16];
- MD5_String2binary(string,digest);
+ MD5_String2binary(string,(char*)digest);
sprintf(output,
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
digest[ 0], digest[ 1], digest[ 2], digest[ 3],
diff --git a/src/lib/zconf_win32.h b/src/lib/zconf_win32.h
new file mode 100644
index 000000000..6d450fc79
--- /dev/null
+++ b/src/lib/zconf_win32.h
@@ -0,0 +1,279 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef _ZCONF_H
+#define _ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+# define deflateInit_ z_deflateInit_
+# define deflate z_deflate
+# define deflateEnd z_deflateEnd
+# define inflateInit_ z_inflateInit_
+# define inflate z_inflate
+# define inflateEnd z_inflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateCopy z_deflateCopy
+# define deflateReset z_deflateReset
+# define deflateParams z_deflateParams
+# define inflateInit2_ z_inflateInit2_
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateReset z_inflateReset
+# define compress z_compress
+# define compress2 z_compress2
+# define uncompress z_uncompress
+# define adler32 z_adler32
+# define crc32 z_crc32
+# define get_crc_table z_get_crc_table
+
+# define Byte z_Byte
+# define uInt z_uInt
+# define uLong z_uLong
+# define Bytef z_Bytef
+# define charf z_charf
+# define intf z_intf
+# define uIntf z_uIntf
+# define uLongf z_uLongf
+# define voidpf z_voidpf
+# define voidp z_voidp
+#endif
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+# define WIN32
+#endif
+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
+# ifndef __32BIT__
+# define __32BIT__
+# endif
+#endif
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#if defined(MSDOS) && !defined(__32BIT__)
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
+# define STDC
+#endif
+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
+# ifndef STDC
+# define STDC
+# endif
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const
+# endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
+# define NO_DUMMY_DECL
+#endif
+
+/* Old Borland C incorrectly complains about missing returns: */
+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
+# define NEED_DUMMY_RETURN
+#endif
+
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+#endif
+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
+# ifndef __32BIT__
+# define SMALL_MEDIUM
+# define FAR _far
+# endif
+#endif
+
+/* Compile with -DZLIB_DLL for Windows DLL support */
+#if defined(ZLIB_DLL)
+# if defined(_WINDOWS) || defined(WINDOWS)
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR _cdecl _export
+# endif
+# endif
+# if defined (__BORLANDC__)
+# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
+# include <windows.h>
+# define ZEXPORT __declspec(dllexport) WINAPI
+# define ZEXPORTRVA __declspec(dllexport) WINAPIV
+# else
+# if defined (_Windows) && defined (__DLL__)
+# define ZEXPORT _export
+# define ZEXPORTVA _export
+# endif
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# if defined (ZLIB_DLL)
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+#endif
+
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(MACOS) && !defined(TARGET_OS_MAC)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <sys/types.h> /* for off_t */
+# include <unistd.h> /* for SEEK_* and off_t */
+# define z_off_t off_t
+#endif
+#ifndef SEEK_SET
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+# pragma map(deflateInit_,"DEIN")
+# pragma map(deflateInit2_,"DEIN2")
+# pragma map(deflateEnd,"DEEND")
+# pragma map(inflateInit_,"ININ")
+# pragma map(inflateInit2_,"ININ2")
+# pragma map(inflateEnd,"INEND")
+# pragma map(inflateSync,"INSY")
+# pragma map(inflateSetDictionary,"INSEDI")
+# pragma map(inflate_blocks,"INBL")
+# pragma map(inflate_blocks_new,"INBLNE")
+# pragma map(inflate_blocks_free,"INBLFR")
+# pragma map(inflate_blocks_reset,"INBLRE")
+# pragma map(inflate_codes_free,"INCOFR")
+# pragma map(inflate_codes,"INCO")
+# pragma map(inflate_fast,"INFA")
+# pragma map(inflate_flush,"INFLU")
+# pragma map(inflate_mask,"INMA")
+# pragma map(inflate_set_dictionary,"INSEDI2")
+# pragma map(inflate_copyright,"INCOPY")
+# pragma map(inflate_trees_bits,"INTRBI")
+# pragma map(inflate_trees_dynamic,"INTRDY")
+# pragma map(inflate_trees_fixed,"INTRFI")
+# pragma map(inflate_trees_free,"INTRFR")
+#endif
+
+#endif /* _ZCONF_H */
diff --git a/src/lib/zlib_win32.h b/src/lib/zlib_win32.h
new file mode 100644
index 000000000..3cd63c939
--- /dev/null
+++ b/src/lib/zlib_win32.h
@@ -0,0 +1,893 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.1.3, July 9th, 1998
+
+ Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef _ZLIB_H
+#define _ZLIB_H
+
+#include "zconf_win32.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.1.3"
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed
+ data. This version of the library supports only one compression method
+ (deflation) but other algorithms will be added later and will have the same
+ stream interface.
+
+ Compression can be done in a single step if the buffers are large
+ enough (for example if an input file is mmap'ed), or can be done by
+ repeated calls of the compression function. In the latter case, the
+ application must provide more input and/or consume the output
+ (providing more output space) before each call.
+
+ The library also supports reading and writing files in gzip (.gz) format
+ with an interface similar to that of stdio.
+
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never
+ crash even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total nb of input bytes read so far */
+
+ Bytef *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total nb of bytes output so far */
+
+ char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidpf opaque; /* private data object passed to zalloc and zfree */
+
+ int data_type; /* best guess about the data type: ascii or binary */
+ uLong adler; /* adler32 value of the uncompressed data */
+ uLong reserved; /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+ The application must update next_in and avail_in when avail_in has
+ dropped to zero. It must update next_out and avail_out when avail_out
+ has dropped to zero. The application must initialize zalloc, zfree and
+ opaque before calling the init function. All other fields are set by the
+ compression library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
+ thread safe.
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this
+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
+ have their offset normalized to zero. The default allocation function
+ provided by this library ensures this (see zutil.c). To reduce memory
+ requirements and avoid any allocation of 64K objects, at the expense of
+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or
+ progress reports. After compression, total_in holds the total size of
+ the uncompressed data and may be saved for use in the decompressor
+ (particularly if the decompressor wants to decompress everything in
+ a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+/* Allowed flush values; see deflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_ASCII 1
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+ /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is
+ not compatible with the zlib.h header file used by the application.
+ This check is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller.
+ If zalloc and zfree are set to Z_NULL, deflateInit updates them to
+ use default allocation functions.
+
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at
+ all (the input data is simply copied a block at a time).
+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and
+ compression (currently equivalent to level 6).
+
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+ with the version assumed by the caller (ZLIB_VERSION).
+ msg is set to null if there is no error message. deflateInit does not
+ perform any compression: this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+ deflate compresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce some
+ output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. deflate performs one or both of the
+ following actions:
+
+ - Compress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in and avail_in are updated and
+ processing will resume at this point for the next call of deflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
+ Forcing flush frequently degrades the compression ratio, so this parameter
+ should be set only when necessary (in interactive applications).
+ Some output may be provided even if flush is not set.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating avail_in or avail_out accordingly; avail_out
+ should never be zero before the call. The application can consume the
+ compressed output when it wants, for example when the output buffer is full
+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+ and with zero avail_out, it must be called again after making room in the
+ output buffer because there might be more output pending.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+ flushed to the output buffer and the output is aligned on a byte boundary, so
+ that the decompressor can get all input data available so far. (In particular
+ avail_in is zero after the call if enough output space has been provided
+ before the call.) Flushing may degrade compression for some compression
+ algorithms and so it should be used only when necessary.
+
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ the compression.
+
+ If deflate returns with avail_out == 0, this function must be called again
+ with the same value of the flush parameter and more output space (updated
+ avail_out), until the flush is complete (deflate returns with non-zero
+ avail_out).
+
+ If the parameter flush is set to Z_FINISH, pending input is processed,
+ pending output is flushed and deflate returns with Z_STREAM_END if there
+ was enough output space; if deflate returns with Z_OK, this function must be
+ called again with Z_FINISH and more output space (updated avail_out) but no
+ more input data, until it returns with Z_STREAM_END or an error. After
+ deflate has returned Z_STREAM_END, the only possible operations on the
+ stream are deflateReset or deflateEnd.
+
+ Z_FINISH can be used immediately after deflateInit if all the compression
+ is to be done in a single step. In this case, avail_out must be at least
+ 0.1% larger than avail_in plus 12 bytes. If deflate does not return
+ Z_STREAM_END, then it must be called again as described above.
+
+ deflate() sets strm->adler to the adler32 checksum of all input read
+ so far (that is, total_in bytes).
+
+ deflate() may update data_type if it can make a good guess about
+ the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
+ binary. This field is only for information purposes and does not affect
+ the compression algorithm in any manner.
+
+ deflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if all input has been
+ consumed and all output has been produced (only when flush is set to
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
+ (for example avail_in or avail_out was zero).
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+ prematurely (some input or output was discarded). In the error case,
+ msg may be set but then points to a static string (which must not be
+ deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+ Initializes the internal stream state for decompression. The fields
+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
+ value depends on the compression method), inflateInit determines the
+ compression method from the zlib header and allocates all data structures
+ accordingly; otherwise the allocation will be deferred to the first call of
+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+ use default allocation functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller. msg is set to null if there is no error
+ message. inflateInit does not perform any decompression apart from reading
+ the zlib header if present: this will be done by inflate(). (So next_in and
+ avail_in may be modified, but next_out and avail_out are unchanged.)
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+ inflate decompresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may some
+ introduce some output latency (reading input without producing any output)
+ except when forced to flush.
+
+ The detailed semantics are as follows. inflate performs one or both of the
+ following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing
+ will resume at this point for the next call of inflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there
+ is no more input data or no more space in the output buffer (see below
+ about the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating the next_* and avail_* values accordingly.
+ The application can consume the uncompressed output when it wants, for
+ example when the output buffer is full (avail_out == 0), or after each
+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+ must be called again after making room in the output buffer because there
+ might be more output pending.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
+ output as possible to the output buffer. The flushing behavior of inflate is
+ not specified for values of the flush parameter other than Z_SYNC_FLUSH
+ and Z_FINISH, but the current implementation actually flushes as much output
+ as possible anyway.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step
+ (a single call of inflate), the parameter flush should be set to
+ Z_FINISH. In this case all pending input is processed and all pending
+ output is flushed; avail_out must be large enough to hold all the
+ uncompressed data. (The size of the uncompressed data may have been saved
+ by the compressor for this purpose.) The next operation on this stream must
+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+ is never required, but can be used to inform inflate that a faster routine
+ may be used for the single inflate() call.
+
+ If a preset dictionary is needed at this point (see inflateSetDictionary
+ below), inflate sets strm-adler to the adler32 checksum of the
+ dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
+ it sets strm->adler to the adler32 checksum of all output produced
+ so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
+ an error code as described below. At the end of the stream, inflate()
+ checks that its computed adler32 checksum is equal to that saved by the
+ compressor and returns Z_STREAM_END only if the checksum is correct.
+
+ inflate() returns Z_OK if some progress has been made (more input processed
+ or more output produced), Z_STREAM_END if the end of the compressed data has
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+ corrupted (input stream not conforming to the zlib format or incorrect
+ adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
+ (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if no progress is possible or if there was not
+ enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
+ case, the application may then call inflateSync to look for a good
+ compression block.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+ was inconsistent. In the error case, msg may be set but then points to a
+ static string (which must not be deallocated).
+*/
+
+ /* Advanced functions */
+
+/*
+ The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy));
+
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by
+ the caller.
+
+ The method parameter is the compression method. It must be Z_DEFLATED in
+ this version of the library.
+
+ The windowBits parameter is the base two logarithm of the window size
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
+ deflateInit is used instead.
+
+ The memLevel parameter specifies how much memory should be allocated
+ for the internal compression state. memLevel=1 uses minimum memory but
+ is slow and reduces compression ratio; memLevel=9 uses maximum memory
+ for optimal speed. The default value is 8. See zconf.h for total memory
+ usage as a function of windowBits and memLevel.
+
+ The strategy parameter is used to tune the compression algorithm. Use the
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+ filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
+ string match). Filtered data consists mostly of small values with a
+ somewhat random distribution. In this case, the compression algorithm is
+ tuned to compress them better. The effect of Z_FILTERED is to force more
+ Huffman coding and less string matching; it is somewhat intermediate
+ between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
+ the compression ratio but not the correctness of the compressed output even
+ if it is not set appropriately.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
+ method). msg is set to null if there is no error message. deflateInit2 does
+ not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the compression dictionary from the given byte sequence
+ without producing any compressed output. This function must be called
+ immediately after deflateInit, deflateInit2 or deflateReset, before any
+ call of deflate. The compressor and decompressor must use exactly the same
+ dictionary (see inflateSetDictionary).
+
+ The dictionary should consist of strings (byte sequences) that are likely
+ to be encountered later in the data to be compressed, with the most commonly
+ used strings preferably put towards the end of the dictionary. Using a
+ dictionary is most useful when the data to be compressed is short and can be
+ predicted with good accuracy; the data can then be compressed better than
+ with the default empty dictionary.
+
+ Depending on the size of the compression data structures selected by
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
+ discarded, for example if the dictionary is larger than the window size in
+ deflate or deflate2. Thus the strings most likely to be useful should be
+ put at the end of the dictionary, not at the front.
+
+ Upon return of this function, strm->adler is set to the Adler32 value
+ of the dictionary; the decompressor may later use this value to determine
+ which dictionary has been used by the compressor. (The Adler32 value
+ applies to the whole dictionary even if only a subset of the dictionary is
+ actually used by the compressor.)
+
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+ parameter is invalid (such as NULL dictionary) or the stream state is
+ inconsistent (for example if deflate has already been called for this stream
+ or if the compression method is bsort). deflateSetDictionary does not
+ perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when several compression strategies will be
+ tried, for example when there are several ways of pre-processing the input
+ data with a filter. The streams that will be discarded should then be freed
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
+ compression state which can be quite large, so this strategy is slow and
+ can consume lots of memory.
+
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to deflateEnd followed by deflateInit,
+ but does not free and reallocate all the internal compression state.
+ The stream will keep the same compression level and any other attributes
+ that may have been set by deflateInit2.
+
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+ int level,
+ int strategy));
+/*
+ Dynamically update the compression level and compression strategy. The
+ interpretation of level and strategy is as in deflateInit2. This can be
+ used to switch between compression and straight copy of the input data, or
+ to switch to a different kind of input data requiring a different
+ strategy. If the compression level is changed, the input available so far
+ is compressed with the old level (and may be flushed); the new level will
+ take effect only at the next call of deflate().
+
+ Before the call of deflateParams, the stream state must be set as for
+ a call of deflate(), since the currently available input may have to
+ be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+ if strm->avail_out was zero.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+ int windowBits));
+
+ This is another version of inflateInit with an extra parameter. The
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+ before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. If a compressed stream with a larger window size is given as
+ input, inflate() will return with the error code Z_DATA_ERROR instead of
+ trying to allocate a larger window.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
+ memLevel). msg is set to null if there is no error message. inflateInit2
+ does not perform any decompression apart from reading the zlib header if
+ present: this will be done by inflate(). (So next_in and avail_in may be
+ modified, but next_out and avail_out are unchanged.)
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the decompression dictionary from the given uncompressed byte
+ sequence. This function must be called immediately after a call of inflate
+ if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the Adler32 value returned by this call of
+ inflate. The compressor and decompressor must use exactly the same
+ dictionary (see deflateSetDictionary).
+
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+ parameter is invalid (such as NULL dictionary) or the stream state is
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+ expected one (incorrect Adler32 value). inflateSetDictionary does not
+ perform any decompression: this will be done by subsequent calls of
+ inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+ Skips invalid compressed data until a full flush point (see above the
+ description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+ if no more input was provided, Z_DATA_ERROR if no flush point has been found,
+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+ case, the application may save the current current value of total_in which
+ indicates where valid compressed data was found. In the error case, the
+ application may repeatedly call inflateSync, providing more input each time,
+ until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate all the internal decompression state.
+ The stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+
+ /* utility functions */
+
+/*
+ The following utility functions are implemented on top of the
+ basic stream-oriented functions. To simplify the interface, some
+ default options are assumed (compression level and memory usage,
+ standard memory allocation functions). The source code of these
+ utility functions can easily be modified if you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Compresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be at least 0.1% larger than
+ sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
+ compressed buffer.
+ This function can be used to compress a whole file at once if the
+ input file is mmap'ed.
+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level));
+/*
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least 0.1% larger than sourceLen plus
+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be large enough to hold the
+ entire uncompressed data. (The size of the uncompressed data must have
+ been saved previously by the compressor and transmitted to the decompressor
+ by some mechanism outside the scope of this compression library.)
+ Upon exit, destLen is the actual size of the compressed buffer.
+ This function can be used to decompress a whole file at once if the
+ input file is mmap'ed.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+
+
+typedef voidp gzFile;
+
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+/*
+ Opens a gzip (.gz) file for reading or writing. The mode parameter
+ is as in fopen ("rb" or "wb") but can also include a compression level
+ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
+ Huffman only compression as in "wb1h". (See the description
+ of deflateInit2 for more information about the strategy parameter.)
+
+ gzopen can be used to read a file which is not in gzip format; in this
+ case gzread will directly read from the file without decompression.
+
+ gzopen returns NULL if the file could not be opened or if there was
+ insufficient memory to allocate the (de)compression state; errno
+ can be checked to distinguish the two cases (if errno is zero, the
+ zlib error is Z_MEM_ERROR). */
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+ gzdopen() associates a gzFile with the file descriptor fd. File
+ descriptors are obtained from calls like open, dup, creat, pipe or
+ fileno (in the file has been previously opened with fopen).
+ The mode parameter is as in gzopen.
+ The next call of gzclose on the returned gzFile will also close the
+ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
+ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
+ gzdopen returns NULL if there was insufficient memory to allocate
+ the (de)compression state.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+ Dynamically update the compression level or strategy. See the description
+ of deflateInit2 for the meaning of these parameters.
+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+ opened for writing.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+ Reads the given number of uncompressed bytes from the compressed file.
+ If the input file was not in gzip format, gzread copies the given number
+ of bytes into the buffer.
+ gzread returns the number of uncompressed bytes actually read (0 for
+ end of file, -1 for error). */
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+ const voidp buf, unsigned len));
+/*
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of uncompressed bytes actually written
+ (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
+/*
+ Converts, formats, and writes the args to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+ Reads bytes from the compressed file until len-1 characters are read, or
+ a newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. The string is then terminated with a null
+ character.
+ gzgets returns buf, or Z_NULL in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+ Writes c, converted to an unsigned char, into the compressed file.
+ gzputc returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+ Reads one byte from the compressed file. gzgetc returns this byte
+ or -1 in case of end of file or error.
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+ Flushes all pending output into the compressed file. The parameter
+ flush is as in the deflate() function. The return value is the zlib
+ error number (see function gzerror below). gzflush returns Z_OK if
+ the flush parameter is Z_FINISH and all output could be flushed.
+ gzflush should be called only when strictly necessary because it can
+ degrade compression.
+*/
+
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+/*
+ Sets the starting position for the next gzread or gzwrite on the
+ given compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
+ the value SEEK_END is not supported.
+ If the file is opened for reading, this function is emulated but can be
+ extremely slow. If the file is opened for writing, only forward seeks are
+ supported; gzseek then compresses a sequence of zeroes up to the new
+ starting position.
+
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error, in
+ particular if the file is opened for writing and the new starting position
+ would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
+/*
+ Rewinds the given file. This function is supported only for reading.
+
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
+/*
+ Returns the starting position for the next gzread or gzwrite on the
+ given compressed file. This position represents a number of bytes in the
+ uncompressed data stream.
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+ Returns 1 when EOF has previously been detected reading the given
+ input stream, otherwise zero.
+*/
+
+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
+/*
+ Flushes all pending output if necessary, closes the compressed file
+ and deallocates all the (de)compression state. The return value is the zlib
+ error number (see function gzerror below).
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+ Returns the error message for the last error which occurred on the
+ given compressed file. errnum is set to zlib error number. If an
+ error occurred in the file system and not in the compression library,
+ errnum is set to Z_ERRNO and the application may consult errno
+ to get the exact error code.
+*/
+
+ /* checksum functions */
+
+/*
+ These functions are not related to compression but are exported
+ anyway because they might be useful in applications using the
+ compression library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is NULL, this function returns
+ the required initial value for the checksum.
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster. Usage example:
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+/*
+ Update a running crc with the bytes buf[0..len-1] and return the updated
+ crc. If buf is NULL, this function returns the required initial value
+ for the crc. Pre- and post-conditioning (one's complement) is performed
+ within this function so it shouldn't be done by the application.
+ Usage example:
+
+ uLong crc = crc32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = crc32(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+*/
+
+
+ /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
+ const char *version, int stream_size));
+#define deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+
+
+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
+ struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+ZEXTERN const char * ZEXPORT zError OF((int err));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ZLIB_H */
diff --git a/src/login/GNUmakefile b/src/login/GNUmakefile
deleted file mode 100644
index 300737cbf..000000000
--- a/src/login/GNUmakefile
+++ /dev/null
@@ -1,13 +0,0 @@
-all: login-server
-txt: login-server
-
-COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o ../common/lock.o ../common/malloc.o ../common/showmsg.o
-COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/db.h ../common/lock.h ../common/malloc.h ../common/showmsg.h
-
-login-server: login.o md5calc.o $(COMMON_OBJ)
- $(CC) -o ../../$@ login.o md5calc.o $(COMMON_OBJ)
-login.o: login.c login.h md5calc.h $(COMMON_H)
-md5calc.o: md5calc.c md5calc.h
-
-clean:
- rm -f *.o ../../login-server
diff --git a/src/login/Makefile b/src/login/Makefile
index 300737cbf..01810b1d1 100644
--- a/src/login/Makefile
+++ b/src/login/Makefile
@@ -1,11 +1,12 @@
all: login-server
txt: login-server
-COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o ../common/lock.o ../common/malloc.o ../common/showmsg.o
-COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/db.h ../common/lock.h ../common/malloc.h ../common/showmsg.h
+COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o ../common/obj/db.o ../common/obj/lock.o ../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/strlib.o
+COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/db.h ../common/lock.h ../common/malloc.h ../common/showmsg.h ../common/strlib.h
login-server: login.o md5calc.o $(COMMON_OBJ)
- $(CC) -o ../../$@ login.o md5calc.o $(COMMON_OBJ)
+ $(CC) -o ../../$@ login.o md5calc.o $(COMMON_OBJ) $(LIB_S)
+
login.o: login.c login.h md5calc.h $(COMMON_H)
md5calc.o: md5calc.c md5calc.h
diff --git a/src/login/login.c b/src/login/login.c
index 8d7ce12a2..733411f56 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -2,20 +2,36 @@
// new version of the login-server by [Yor]
#include <sys/types.h>
+#ifdef __WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <winsock2.h>
+#include <time.h>
+void Gettimeofday(struct timeval *timenow)
+{
+ time_t t;
+ t = clock();
+ timenow->tv_usec = t;
+ timenow->tv_sec = t / CLK_TCK;
+ return;
+}
+#define gettimeofday(timenow, dummy) Gettimeofday(timenow)
+#define in_addr_t unsigned long
+#else
#include <sys/socket.h>
-#include <stdio.h>
-#include <stdlib.h>
#include <netinet/in.h>
#include <sys/time.h>
-#include <time.h>
#include <sys/ioctl.h>
-#include <sys/stat.h> // for stat/lstat/fstat
#include <unistd.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/stat.h> // for stat/lstat/fstat
#include <signal.h>
#include <fcntl.h>
#include <string.h>
-#include <arpa/inet.h>
-#include <netdb.h>
#include <stdarg.h>
#include "../common/core.h"
@@ -27,6 +43,8 @@
#include "../common/db.h"
#include "../common/lock.h"
#include "../common/malloc.h"
+#include "../common/buffer.h"
+#include "../common/strlib.h"
#ifdef PASSWORDENC
#include "md5calc.h"
@@ -39,6 +57,8 @@
int account_id_count = START_ACCOUNT_NUM;
int server_num;
int new_account_flag = 0;
+char bind_ip_str[16];
+in_addr_t bind_ip;
int login_port = 6900;
char lan_char_ip[16];
int subneti[4];
@@ -54,15 +74,14 @@ int save_unknown_packets = 0;
long creation_time_GM_account_file;
int gm_account_filename_check_timer = 15; // Timer to check if GM_account file has been changed and reload GM account automaticaly (in seconds; default: 15)
+int log_login = 1;
+
int display_parse_login = 0; // 0: no, 1: yes
int display_parse_admin = 0; // 0: no, 1: yes
int display_parse_fromchar = 0; // 0: no, 1: yes (without packet 0x2714), 2: all packets
struct mmo_char_server server[MAX_SERVERS];
int server_fd[MAX_SERVERS];
-int server_freezeflag[MAX_SERVERS]; // Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed
-int anti_freeze_enable = 0;
-int ANTI_FREEZE_INTERVAL = 15;
int login_fd;
@@ -94,6 +113,11 @@ int add_to_unlimited_account = 0; // Give possibility or not to adjust (ladmin c
int start_limited_time = -1; // Starting additional sec from now for the limited time at creation of accounts (-1: unlimited time, 0 or more: additional sec from now)
int check_ip_flag = 1; // It's to check IP of a player between login-server and char-server (part of anti-hacking system)
+int check_client_version = 0; //Client version check ON/OFF .. (sirius)
+int client_version_to_connect = 20; //Client version needed to connect ..(sirius)
+
+
+
struct login_session_data {
int md5keylen;
char md5key[20];
@@ -141,6 +165,8 @@ int level_new_gm = 60;
struct gm_account *gm_account_db;
+static struct dbt *online_db;
+
int dynamic_pass_failure_ban = 1;
int dynamic_pass_failure_ban_time = 5;
int dynamic_pass_failure_ban_how_many = 3;
@@ -154,31 +180,52 @@ int console = 0;
// Writing function of logs file
//------------------------------
int login_log(char *fmt, ...) {
- va_list ap;
- struct timeval tv;
- char tmpstr[2048];
+ if (log_login) {
+ va_list ap;
+ struct timeval tv;
+ char tmpstr[2048];
- if(!log_fp)
- log_fp = fopen(login_log_filename, "a");
+ if(!log_fp)
+ log_fp = fopen(login_log_filename, "a");
- log_fp = fopen(login_log_filename, "a");
- if (log_fp) {
- if (fmt[0] == '\0') // jump a line if no message
- fprintf(log_fp, RETCODE);
- else {
- va_start(ap, fmt);
- gettimeofday(&tv, NULL);
- strftime(tmpstr, 24, date_format, localtime(&(tv.tv_sec)));
- sprintf(tmpstr + strlen(tmpstr), ".%03d: %s", (int)tv.tv_usec / 1000, fmt);
- vfprintf(log_fp, tmpstr, ap);
- va_end(ap);
+ if (log_fp) {
+ if (fmt[0] == '\0') // jump a line if no message
+ fprintf(log_fp, RETCODE);
+ else {
+ va_start(ap, fmt);
+ gettimeofday(&tv, NULL);
+ strftime(tmpstr, 24, date_format, localtime((const time_t*)&(tv.tv_sec)));
+ sprintf(tmpstr + strlen(tmpstr), ".%03d: %s", (int)tv.tv_usec / 1000, fmt);
+ vfprintf(log_fp, tmpstr, ap);
+ va_end(ap);
+ }
+ fflush(log_fp); // under cygwin or windows, if software is stopped, data are not written in the file -> fflush at every line
}
- fflush(log_fp); // under cygwin or windows, if software is stopped, data are not written in the file -> fflush at every line
}
return 0;
}
+//-----------------------------------------------------
+// Online User Database [Wizputer]
+//-----------------------------------------------------
+
+void add_online_user (int account_id) {
+ int *p;
+ p = (int *)aMalloc(sizeof(int));
+ *p = account_id;
+ numdb_insert(online_db, account_id, p);
+}
+int is_user_online (int account_id) {
+ int *p = (int*)numdb_search(online_db, account_id);
+ return (p != NULL);
+}
+void remove_online_user (int account_id) {
+ int *p;
+ p = (int*)numdb_erase(online_db, account_id);
+ aFree(p);
+}
+
//----------------------------------------------------------------------
// Determine if an account (id) is a GM account
// and returns its level (or 0 if it isn't a GM account or if not found)
@@ -213,12 +260,12 @@ void addGM(int account_id, int level) {
}
return;
}
-
+
// if new account
if (i == GM_num && do_add) {
if (GM_num >= GM_max) {
GM_max += 256;
- gm_account_db = realloc(gm_account_db, sizeof(struct gm_account) * GM_max);
+ gm_account_db = (struct gm_account*)aRealloc(gm_account_db, sizeof(struct gm_account) * GM_max);
memset(gm_account_db + (GM_max - 256), 0, sizeof(struct gm_account) * 256);
}
gm_account_db[GM_num].account_id = account_id;
@@ -242,7 +289,7 @@ int read_gm_account() {
struct stat file_stat;
int start_range = 0, end_range = 0, is_range = 0, current_id = 0;
- if(gm_account_db) free(gm_account_db);
+ if(gm_account_db) aFree(gm_account_db);
GM_num = 0;
if(GM_max < 0) GM_max = 256;
gm_account_db = (struct gm_account*)aCalloc(GM_max, sizeof(struct gm_account));
@@ -283,7 +330,7 @@ int read_gm_account() {
printf("read_gm_account: file [%s] invalid range, beginning of range is equal to end of range (line #%d).\n", GM_account_filename, line_counter);
else if (start_range>end_range)
printf("read_gm_account: file [%s] invalid range, beginning of range must be lower than end of range (line #%d).\n", GM_account_filename, line_counter);
- else
+ else
for (current_id = start_range;current_id<=end_range;current_id++)
addGM(current_id,level);
} else {
@@ -307,14 +354,14 @@ int check_ipmask(unsigned int ip, const unsigned char *str) {
unsigned int mask = 0, i = 0, m, ip2, a0, a1, a2, a3;
unsigned char *p = (unsigned char *)&ip2, *p2 = (unsigned char *)&mask;
- if (sscanf(str, "%d.%d.%d.%d/%n", &a0, &a1, &a2, &a3, &i) != 4 || i == 0)
+ if (sscanf((const char*)str, "%d.%d.%d.%d/%n", &a0, &a1, &a2, &a3, &i) != 4 || i == 0)
return 0;
p[0] = a0; p[1] = a1; p[2] = a2; p[3] = a3;
- if (sscanf(str+i, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) == 4) {
+ if (sscanf((const char*)str+i, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) == 4) {
p2[0] = a0; p2[1] = a1; p2[2] = a2; p2[3] = a3;
mask = ntohl(mask);
- } else if (sscanf(str+i, "%d", &m) == 1 && m >= 0 && m <= 32) {
+ } else if (sscanf((const char*)(str+i), "%d", &m) == 1 && m >= 0 && m <= 32) {
for(i = 0; i < m && i < 32; i++)
mask = (mask >> 1) | 0x80000000;
} else {
@@ -353,7 +400,7 @@ int check_ip(unsigned int ip) {
for(i = 0; i < access_allownum; i++) {
access_ip = access_allow + i * ACO_STRSIZE;
- if (memcmp(access_ip, buf, strlen(access_ip)) == 0 || check_ipmask(ip, access_ip)) {
+ if (memcmp(access_ip, buf, strlen(access_ip)) == 0 || check_ipmask(ip, (unsigned char*)access_ip)) {
if(access_order == ACO_ALLOW_DENY)
return 1; // With 'allow, deny' (deny if not allow), allow has priority
flag = ACF_ALLOW;
@@ -363,7 +410,7 @@ int check_ip(unsigned int ip) {
for(i = 0; i < access_denynum; i++) {
access_ip = access_deny + i * ACO_STRSIZE;
- if (memcmp(access_ip, buf, strlen(access_ip)) == 0 || check_ipmask(ip, access_ip)) {
+ if (memcmp(access_ip, buf, strlen(access_ip)) == 0 || check_ipmask(ip, (unsigned char*)access_ip)) {
//flag = ACF_DENY; // not necessary to define flag
return 0; // At this point, if it's 'deny', we refuse connection.
}
@@ -401,7 +448,7 @@ int check_ladminip(unsigned int ip) {
for(i = 0; i < access_ladmin_allownum; i++) {
access_ip = access_ladmin_allow + i * ACO_STRSIZE;
- if (memcmp(access_ip, buf, strlen(access_ip)) == 0 || check_ipmask(ip, access_ip)) {
+ if (memcmp(access_ip, buf, strlen(access_ip)) == 0 || check_ipmask(ip, (unsigned char*)access_ip)) {
return 1;
}
}
@@ -409,29 +456,12 @@ int check_ladminip(unsigned int ip) {
return 0;
}
-//-----------------------------------------------------
-// Function to suppress control characters in a string.
-//-----------------------------------------------------
-int remove_control_chars(unsigned char *str) {
- int i;
- int change = 0;
-
- for(i = 0; str[i]; i++) {
- if (str[i] < 32) {
- str[i] = '_';
- change = 1;
- }
- }
-
- return change;
-}
-
//---------------------------------------------------
// E-mail check: return 0 (not correct) or 1 (valid).
//---------------------------------------------------
-int e_mail_check(unsigned char *email) {
+int e_mail_check(char *email) {
char ch;
- unsigned char* last_arobas;
+ char* last_arobas;
// athena limits
if (strlen(email) < 3 || strlen(email) > 39)
@@ -577,7 +607,7 @@ int mmo_auth_init(void) {
continue;
}
userid[23] = '\0';
- remove_control_chars(userid);
+ remove_control_chars((unsigned char *)userid);
for(j = 0; j < auth_num; j++) {
if (auth_dat[j].account_id == account_id) {
printf("\033[1;31mmmo_auth_init: ******Error: an account has an identical id to another.\n");
@@ -590,8 +620,8 @@ int mmo_auth_init(void) {
printf("\033[1;31mmmo_auth_init: ******Error: account name already exists.\n");
printf(" account name '%s' -> new account not read.\n", userid); // 2 lines, account name can be long.
printf(" Account saved in log file.\033[0m\n");
- login_log("mmmo_auth_init: ******Error: an account has an identical id to another." RETCODE);
- login_log(" account id #%d -> new account not read (saved in next line):" RETCODE, account_id);
+ login_log("mmmo_auth_init: ******Error: an account has an identical name to another." RETCODE);
+ login_log(" account name '%s' -> new account not read (saved in next line):" RETCODE, userid);
login_log("%s", line);
break;
}
@@ -601,7 +631,7 @@ int mmo_auth_init(void) {
if (auth_num >= auth_max) {
auth_max += 256;
- auth_dat = realloc(auth_dat, sizeof(struct auth_dat) * auth_max);
+ auth_dat = (struct auth_dat*)aRealloc(auth_dat, sizeof(struct auth_dat) * auth_max);
}
memset(&auth_dat[auth_num], '\0', sizeof(struct auth_dat));
@@ -611,11 +641,11 @@ int mmo_auth_init(void) {
strncpy(auth_dat[auth_num].userid, userid, 24);
pass[23] = '\0';
- remove_control_chars(pass);
+ remove_control_chars((unsigned char *)pass);
strncpy(auth_dat[auth_num].pass, pass, 24);
lastlogin[23] = '\0';
- remove_control_chars(lastlogin);
+ remove_control_chars((unsigned char *)lastlogin);
strncpy(auth_dat[auth_num].lastlogin, lastlogin, 24);
auth_dat[auth_num].sex = (sex == 'S' || sex == 's') ? 2 : (sex == 'M' || sex == 'm');
@@ -636,12 +666,12 @@ int mmo_auth_init(void) {
printf("Account %s (%d): invalid e-mail (replaced par a@a.com).\n", auth_dat[auth_num].userid, auth_dat[auth_num].account_id);
strncpy(auth_dat[auth_num].email, "a@a.com", 40);
} else {
- remove_control_chars(email);
+ remove_control_chars((unsigned char *)email);
strncpy(auth_dat[auth_num].email, email, 40);
}
error_message[19] = '\0';
- remove_control_chars(error_message);
+ remove_control_chars((unsigned char *)error_message);
if (error_message[0] == '\0' || state != 7) { // 7, because state is packet 0x006a value + 1
strncpy(auth_dat[auth_num].error_message, "-", 20);
} else {
@@ -656,11 +686,11 @@ int mmo_auth_init(void) {
auth_dat[auth_num].connect_until_time = connect_until_time;
last_ip[15] = '\0';
- remove_control_chars(last_ip);
+ remove_control_chars((unsigned char *)last_ip);
strncpy(auth_dat[auth_num].last_ip, last_ip, 16);
memo[254] = '\0';
- remove_control_chars(memo);
+ remove_control_chars((unsigned char *)memo);
strncpy(auth_dat[auth_num].memo, memo, 255);
for(j = 0; j < ACCOUNT_REG2_NUM; j++) {
@@ -675,7 +705,7 @@ int mmo_auth_init(void) {
break;
}
str[31] = '\0';
- remove_control_chars(str);
+ remove_control_chars((unsigned char *)str);
strncpy(auth_dat[auth_num].account_reg2[j].str, str, 32);
auth_dat[auth_num].account_reg2[j].value = v;
}
@@ -702,7 +732,7 @@ int mmo_auth_init(void) {
continue;
}
userid[23] = '\0';
- remove_control_chars(userid);
+ remove_control_chars((unsigned char *)userid);
for(j = 0; j < auth_num; j++) {
if (auth_dat[j].account_id == account_id) {
printf("\033[1;31mmmo_auth_init: ******Error: an account has an identical id to another.\n");
@@ -726,7 +756,7 @@ int mmo_auth_init(void) {
if (auth_num >= auth_max) {
auth_max += 256;
- auth_dat = realloc(auth_dat, sizeof(struct auth_dat) * auth_max);
+ auth_dat = (struct auth_dat*)aRealloc(auth_dat, sizeof(struct auth_dat) * auth_max);
}
memset(&auth_dat[auth_num], '\0', sizeof(struct auth_dat));
@@ -736,11 +766,11 @@ int mmo_auth_init(void) {
strncpy(auth_dat[auth_num].userid, userid, 24);
pass[23] = '\0';
- remove_control_chars(pass);
+ remove_control_chars((unsigned char *)pass);
strncpy(auth_dat[auth_num].pass, pass, 24);
lastlogin[23] = '\0';
- remove_control_chars(lastlogin);
+ remove_control_chars((unsigned char *)lastlogin);
strncpy(auth_dat[auth_num].lastlogin, lastlogin, 24);
auth_dat[auth_num].sex = (sex == 'S' || sex == 's') ? 2 : (sex == 'M' || sex == 'm');
@@ -783,7 +813,7 @@ int mmo_auth_init(void) {
break;
}
str[31] = '\0';
- remove_control_chars(str);
+ remove_control_chars((unsigned char *)str);
strncpy(auth_dat[auth_num].account_reg2[j].str, str, 32);
auth_dat[auth_num].account_reg2[j].value = v;
}
@@ -852,7 +882,9 @@ void mmo_auth_sync(void) {
FILE *fp;
int i, j, k, lock;
int account_id;
- int id[auth_num];
+ //int id[auth_num];
+ //int *id = (int *)aCalloc(auth_num, sizeof(int));
+ CREATE_BUFFER(id, int, auth_num);
char line[65536];
// Sorting before save
@@ -870,8 +902,11 @@ void mmo_auth_sync(void) {
}
// Data save
- if ((fp = lock_fopen(account_filename, &lock)) == NULL)
+ if ((fp = lock_fopen(account_filename, &lock)) == NULL) {
+ //if (id) aFree(id); // aFree, right?
+ DELETE_BUFFER(id);
return;
+ }
fprintf(fp, "// Accounts file: here are saved all information about the accounts.\n");
fprintf(fp, "// Structure: ID, account name, password, last login time, sex, # of logins, state, email, error message for state 7, validity time, last (accepted) login ip, memo field, ban timestamp, repeated(register text, register value)\n");
@@ -902,6 +937,9 @@ void mmo_auth_sync(void) {
if (auth_before_save_file < AUTH_BEFORE_SAVE_FILE)
auth_before_save_file = AUTH_BEFORE_SAVE_FILE;
+ //if (id) aFree(id);
+ DELETE_BUFFER(id);
+
return;
}
@@ -947,7 +985,7 @@ int charif_sendallwos(int sfd, unsigned char *buf, unsigned int len) {
//-----------------------------------------------------
void send_GM_accounts() {
int i;
- char buf[32767];
+ unsigned char buf[32767];
int len;
len = 4;
@@ -1000,8 +1038,7 @@ int mmo_auth_new(struct mmo_account* account, char sex, char* email) {
if (auth_num >= auth_max) {
auth_max += 256;
- auth_dat = realloc(auth_dat, sizeof(struct auth_dat) * auth_max);
- memset(auth_dat, 0, sizeof(struct auth_dat) * auth_max);
+ auth_dat = (struct auth_dat*)aRealloc(auth_dat, sizeof(struct auth_dat) * auth_max);
}
memset(&auth_dat[i], '\0', sizeof(struct auth_dat));
@@ -1086,7 +1123,14 @@ int mmo_auth(struct mmo_account* account, int fd) {
newaccount = 1;
account->userid[len] = '\0';
}
-
+
+ //EXE Version check [Sirius]
+ if(check_client_version == 1 && account->version != 0){
+ if(account->version != client_version_to_connect){
+ return 5;
+ }
+ }
+
// Strict account search
for(i = 0; i < auth_num; i++) {
if (strcmp(account->userid, auth_dat[i].userid) == 0)
@@ -1113,7 +1157,7 @@ int mmo_auth(struct mmo_account* account, int fd) {
memcpy(user_password, account->passwd, 25);
encpasswdok = 0;
#ifdef PASSWORDENC
- ld = session[fd]->session_data;
+ ld = (struct login_session_data*)session[fd]->session_data;
if (account->passwdenc > 0) {
int j = account->passwdenc;
if (!ld) {
@@ -1215,7 +1259,7 @@ int mmo_auth(struct mmo_account* account, int fd) {
}
gettimeofday(&tv, NULL);
- strftime(tmpstr, 24, date_format, localtime(&(tv.tv_sec)));
+ strftime(tmpstr, 24, date_format, localtime((const time_t*)&(tv.tv_sec)));
sprintf(tmpstr + strlen(tmpstr), ".%03d", (int)tv.tv_usec / 1000);
account->account_id = auth_dat[i].account_id;
@@ -1235,32 +1279,6 @@ int mmo_auth(struct mmo_account* account, int fd) {
return -1; // account OK
}
-//-------------------------------
-// Char-server anti-freeze system
-//-------------------------------
-int char_anti_freeze_system(int tid, unsigned int tick, int id, int data) {
- int i;
-
- //printf("Entering in char_anti_freeze_system function to check freeze of servers.\n");
- for(i = 0; i < MAX_SERVERS; i++) {
- if (server_fd[i] >= 0) {// if char-server is online
- //printf("char_anti_freeze_system: server #%d '%s', flag: %d.\n", i, server[i].name, server_freezeflag[i]);
- if (server_freezeflag[i]-- < 1) { // Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed
- printf("Char-server anti-freeze system: char-server #%d '%s' is freezed -> disconnection.\n", i, server[i].name);
- login_log("Char-server anti-freeze system: char-server #%d '%s' is freezed -> disconnection." RETCODE,
- i, server[i].name);
- session[server_fd[i]]->eof = 1;
- } else {
- // send alive packet to check connection
- WFIFOW(server_fd[i],0) = 0x2718;
- WFIFOSET(server_fd[i],2);
- }
- }
- }
-
- return 0;
-}
-
//--------------------------------
// Packet parsing for char-servers
//--------------------------------
@@ -1367,13 +1385,15 @@ int parse_fromchar(int fd) {
return 0;
//printf("parse_fromchar: Receiving of the users number of the server '%s': %d\n", server[id].name, RFIFOL(fd,2));
server[id].users = RFIFOL(fd,2);
- if(anti_freeze_enable)
- server_freezeflag[id] = 5; // Char anti-freeze system. Counter. 5 ok, 4...0 freezed
+ // send some answer
+ WFIFOW(fd,0) = 0x2718;
+ WFIFOSET(fd,2);
+
RFIFOSKIP(fd,6);
break;
// we receive a e-mail creation of an account with a default e-mail (no answer)
- case 0x2715:
+ case 0x2715:
if (RFIFOREST(fd) < 46)
return 0;
{
@@ -1381,7 +1401,7 @@ int parse_fromchar(int fd) {
acc = RFIFOL(fd,2); // speed up
memcpy(email, RFIFOP(fd,6), 40);
email[39] = '\0';
- remove_control_chars(email);
+ remove_control_chars((unsigned char *)email);
//printf("parse_fromchar: an e-mail creation of an account with a default e-mail: server '%s', account: %d, e-mail: '%s'.\n", server[id].name, acc, RFIFOP(fd,6));
if (e_mail_check(email) == 0)
login_log("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - e-mail is invalid (account: %d, ip: %s)" RETCODE,
@@ -1439,7 +1459,7 @@ int parse_fromchar(int fd) {
WBUFW(buf,0) = 0x2721;
WBUFL(buf,2) = acc;
WBUFL(buf,6) = 0;
- if (strcmp(RFIFOP(fd,8), gm_pass) == 0) {
+ if (strcmp((char*)RFIFOP(fd,8), gm_pass) == 0) {
// only non-GM can become GM
if (isGM(acc) == 0) {
// if we autorise creation
@@ -1449,7 +1469,7 @@ int parse_fromchar(int fd) {
char tmpstr[24];
struct timeval tv;
gettimeofday(&tv, NULL);
- strftime(tmpstr, 23, date_format, localtime(&(tv.tv_sec)));
+ strftime(tmpstr, 23, date_format, localtime((const time_t*)&(tv.tv_sec)));
fprintf(fp, RETCODE "// %s: @GM command on account %d" RETCODE "%d %d" RETCODE, tmpstr, acc, acc, level_new_gm);
fclose(fp);
WBUFL(buf,6) = level_new_gm;
@@ -1492,10 +1512,10 @@ int parse_fromchar(int fd) {
acc = RFIFOL(fd,2);
memcpy(actual_email, RFIFOP(fd,6), 40);
actual_email[39] = '\0';
- remove_control_chars(actual_email);
+ remove_control_chars((unsigned char *)actual_email);
memcpy(new_email, RFIFOP(fd,46), 40);
new_email[39] = '\0';
- remove_control_chars(new_email);
+ remove_control_chars((unsigned char *)new_email);
if (e_mail_check(actual_email) == 0)
login_log("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual email is invalid (account: %d, ip: %s)" RETCODE,
server[id].name, acc, ip);
@@ -1682,13 +1702,15 @@ int parse_fromchar(int fd) {
acc = RFIFOL(fd,4);
for(i = 0; i < auth_num; i++) {
if (auth_dat[i].account_id == acc) {
- unsigned char buf[RFIFOW(fd,2)+1];
+ //unsigned char buf[RFIFOW(fd,2)+1];
+ unsigned char *buf;
+ buf = (unsigned char*)aCalloc(RFIFOW(fd,2)+1, sizeof(unsigned char));
login_log("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d, ip: %s)." RETCODE,
server[id].name, acc, ip);
for(p = 8, j = 0; p < RFIFOW(fd,2) && j < ACCOUNT_REG2_NUM; p += 36, j++) {
memcpy(auth_dat[i].account_reg2[j].str, RFIFOP(fd,p), 32);
auth_dat[i].account_reg2[j].str[31] = '\0';
- remove_control_chars(auth_dat[i].account_reg2[j].str);
+ remove_control_chars((unsigned char *)auth_dat[i].account_reg2[j].str);
auth_dat[i].account_reg2[j].value = RFIFOL(fd,p+32);
}
auth_dat[i].account_reg2_num = j;
@@ -1699,6 +1721,7 @@ int parse_fromchar(int fd) {
// Save
mmo_auth_sync();
// printf("parse_fromchar: receiving (from the char-server) of account_reg2 (account id: %d).\n", acc);
+ if (buf) free(buf);
break;
}
}
@@ -1735,6 +1758,21 @@ int parse_fromchar(int fd) {
RFIFOSKIP(fd,6);
}
return 0;
+
+ case 0x272b: // Set account_id to online [Wizputer]
+ if (RFIFOREST(fd) < 6)
+ return 0;
+ add_online_user(RFIFOL(fd,2));
+ RFIFOSKIP(fd,6);
+ break;
+
+ case 0x272c: // Set account_id to offline [Wizputer]
+ if (RFIFOREST(fd) < 6)
+ return 0;
+ remove_online_user(RFIFOL(fd,2));
+ RFIFOSKIP(fd,6);
+ break;
+
case 0x3000: //change sex for chrif_changesex()
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
@@ -1774,7 +1812,7 @@ int parse_fromchar(int fd) {
logfp = fopen(login_log_unknown_packets_filename, "a");
if (logfp) {
gettimeofday(&tv, NULL);
- strftime(tmpstr, 23, date_format, localtime(&(tv.tv_sec)));
+ strftime(tmpstr, 23, date_format, localtime((const time_t*)&(tv.tv_sec)));
fprintf(logfp, "%s.%03d: receiving of an unknown packet -> disconnection" RETCODE, tmpstr, (int)tv.tv_usec / 1000);
fprintf(logfp, "parse_fromchar: connection #%d (ip: %s), packet: 0x%x (with being read: %d)." RETCODE, fd, ip, RFIFOW(fd,0), RFIFOREST(fd));
fprintf(logfp, "Detail (in hex):" RETCODE);
@@ -1864,7 +1902,9 @@ int parse_admin(int fd) {
return 0;
{
int st, ed, len;
- int id[auth_num];
+ //int id[auth_num];
+ //int *id=(int *)aCalloc(auth_num, sizeof(int));
+ CREATE_BUFFER(id, int, auth_num);
st = RFIFOL(fd,2);
ed = RFIFOL(fd,6);
RFIFOSKIP(fd,10);
@@ -1908,6 +1948,8 @@ int parse_admin(int fd) {
}
WFIFOW(fd,2) = len;
WFIFOSET(fd,len);
+ //if (id) free(id);
+ DELETE_BUFFER(id);
}
break;
@@ -1916,13 +1958,13 @@ int parse_admin(int fd) {
return 0;
{
struct mmo_account ma;
- ma.userid = RFIFOP(fd, 2);
+ ma.userid = (char*)RFIFOP(fd, 2);
memcpy(ma.passwd, RFIFOP(fd, 26), 24);
ma.passwd[24] = '\0';
memcpy(ma.lastlogin, "-", 2);
ma.sex = RFIFOB(fd,50);
WFIFOW(fd,0) = 0x7931;
- WFIFOL(fd,2) = -1;
+ WFIFOL(fd,2) = 0xffffffff;
memcpy(WFIFOP(fd,6), RFIFOP(fd,2), 24);
if (strlen(ma.userid) > 23 || strlen(ma.passwd) > 23) {
login_log("'ladmin': Attempt to create an invalid account (account or pass is too long, ip: %s)" RETCODE,
@@ -1937,8 +1979,8 @@ int parse_admin(int fd) {
login_log("'ladmin': Attempt to create an account, but there is no more available id number (account: %s, pass: %s, sex: %c, ip: %s)" RETCODE,
ma.userid, ma.passwd, ma.sex, ip);
} else {
- remove_control_chars(ma.userid);
- remove_control_chars(ma.passwd);
+ remove_control_chars((unsigned char *)ma.userid);
+ remove_control_chars((unsigned char *)ma.passwd);
for(i = 0; i < auth_num; i++) {
if (strncmp(auth_dat[i].userid, ma.userid, 24) == 0) {
login_log("'ladmin': Attempt to create an already existing account (account: %s, pass: %s, received pass: %s, ip: %s)" RETCODE,
@@ -1951,7 +1993,7 @@ int parse_admin(int fd) {
char email[40];
memcpy(email, RFIFOP(fd,51), 40);
email[39] = '\0';
- remove_control_chars(email);
+ remove_control_chars((unsigned char *)email);
new_id = mmo_auth_new(&ma, ma.sex, email);
login_log("'ladmin': Account creation (account: %s (id: %d), pass: %s, sex: %c, email: %s, ip: %s)" RETCODE,
ma.userid, new_id, ma.passwd, ma.sex, auth_dat[i].email, ip);
@@ -1968,10 +2010,10 @@ int parse_admin(int fd) {
if (RFIFOREST(fd) < 26)
return 0;
WFIFOW(fd,0) = 0x7933;
- WFIFOL(fd,2) = -1;
- account_name = RFIFOP(fd,2);
+ WFIFOL(fd,2) = 0xFFFFFFFF;
+ account_name = (char*)RFIFOP(fd,2);
account_name[23] = '\0';
- remove_control_chars(account_name);
+ remove_control_chars((unsigned char *)account_name);
i = search_account_index(account_name);
if (i != -1) {
// Char-server is notified of deletion (for characters deletion).
@@ -1985,7 +2027,7 @@ int parse_admin(int fd) {
// save deleted account in log file
login_log("'ladmin': Account deletion (account: %s, id: %d, ip: %s) - saved in next line:" RETCODE,
auth_dat[i].userid, auth_dat[i].account_id, ip);
- mmo_auth_tostr(buf, &auth_dat[i]);
+ mmo_auth_tostr((char*)buf, &auth_dat[i]);
login_log("%s" RETCODE, buf);
// delete account
memset(auth_dat[i].userid, '\0', sizeof(auth_dat[i].userid));
@@ -2004,16 +2046,16 @@ int parse_admin(int fd) {
if (RFIFOREST(fd) < 50)
return 0;
WFIFOW(fd,0) = 0x7935;
- WFIFOL(fd,2) = -1;
- account_name = RFIFOP(fd,2);
+ WFIFOL(fd,2) = 0xFFFFFFFF; /// WTF??? an unsigned being set to a -1
+ account_name = (char*)RFIFOP(fd,2);
account_name[23] = '\0';
- remove_control_chars(account_name);
+ remove_control_chars((unsigned char *)account_name);
i = search_account_index(account_name);
if (i != -1) {
memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
memcpy(auth_dat[i].pass, RFIFOP(fd,26), 24);
auth_dat[i].pass[23] = '\0';
- remove_control_chars(auth_dat[i].pass);
+ remove_control_chars((unsigned char *)auth_dat[i].pass);
WFIFOL(fd,2) = auth_dat[i].account_id;
login_log("'ladmin': Modification of a password (account: %s, new password: %s, ip: %s)" RETCODE,
auth_dat[i].userid, auth_dat[i].pass, ip);
@@ -2034,14 +2076,14 @@ int parse_admin(int fd) {
char error_message[20];
int statut;
WFIFOW(fd,0) = 0x7937;
- WFIFOL(fd,2) = -1;
- account_name = RFIFOP(fd,2);
+ WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
+ account_name = (char*)RFIFOP(fd,2);
account_name[23] = '\0';
- remove_control_chars(account_name);
+ remove_control_chars((unsigned char *)account_name);
statut = RFIFOL(fd,26);
memcpy(error_message, RFIFOP(fd,30), 20);
error_message[19] = '\0';
- remove_control_chars(error_message);
+ remove_control_chars((unsigned char *)error_message);
if (statut != 7 || error_message[0] == '\0') { // 7: // 6 = Your are Prohibited to log in until %s
strcpy(error_message, "-");
}
@@ -2095,7 +2137,7 @@ int parse_admin(int fd) {
memcpy(WFIFOP(fd,4+server_num*32+6), server[i].name, 20);
WFIFOW(fd,4+server_num*32+26) = server[i].users;
WFIFOW(fd,4+server_num*32+28) = server[i].maintenance;
- WFIFOW(fd,4+server_num*32+30) = server[i].new;
+ WFIFOW(fd,4+server_num*32+30) = server[i].new_;
server_num++;
}
}
@@ -2109,17 +2151,17 @@ int parse_admin(int fd) {
if (RFIFOREST(fd) < 50)
return 0;
WFIFOW(fd,0) = 0x793b;
- WFIFOL(fd,2) = -1;
- account_name = RFIFOP(fd,2);
+ WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
+ account_name = (char*)RFIFOP(fd,2);
account_name[23] = '\0';
- remove_control_chars(account_name);
+ remove_control_chars((unsigned char *)account_name);
i = search_account_index(account_name);
if (i != -1) {
char pass[25];
memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
memcpy(pass, RFIFOP(fd,26), 24);
pass[24] = '\0';
- remove_control_chars(pass);
+ remove_control_chars((unsigned char *)pass);
if (strcmp(auth_dat[i].pass, pass) == 0) {
WFIFOL(fd,2) = auth_dat[i].account_id;
login_log("'ladmin': Check of password OK (account: %s, password: %s, ip: %s)" RETCODE,
@@ -2141,10 +2183,10 @@ int parse_admin(int fd) {
if (RFIFOREST(fd) < 27)
return 0;
WFIFOW(fd,0) = 0x793d;
- WFIFOL(fd,2) = -1;
- account_name = RFIFOP(fd,2);
+ WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
+ account_name = (char*)RFIFOP(fd,2);
account_name[23] = '\0';
- remove_control_chars(account_name);
+ remove_control_chars((unsigned char *)account_name);
memcpy(WFIFOP(fd,6), account_name, 24);
{
char sex;
@@ -2193,10 +2235,10 @@ int parse_admin(int fd) {
if (RFIFOREST(fd) < 27)
return 0;
WFIFOW(fd,0) = 0x793f;
- WFIFOL(fd,2) = -1;
- account_name = RFIFOP(fd,2);
+ WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
+ account_name = (char*)RFIFOP(fd,2);
account_name[23] = '\0';
- remove_control_chars(account_name);
+ remove_control_chars((unsigned char *)account_name);
memcpy(WFIFOP(fd,6), account_name, 24);
{
char new_gm_level;
@@ -2221,7 +2263,7 @@ int parse_admin(int fd) {
if ((fp2 = lock_fopen(GM_account_filename, &lock)) != NULL) {
if ((fp = fopen(GM_account_filename, "r")) != NULL) {
gettimeofday(&tv, NULL);
- strftime(tmpstr, 23, date_format, localtime(&(tv.tv_sec)));
+ strftime(tmpstr, 23, date_format, localtime((const time_t*)&(tv.tv_sec)));
modify_flag = 0;
// read/write GM file
while(fgets(line, sizeof(line)-1, fp)) {
@@ -2283,10 +2325,10 @@ int parse_admin(int fd) {
if (RFIFOREST(fd) < 66)
return 0;
WFIFOW(fd,0) = 0x7941;
- WFIFOL(fd,2) = -1;
- account_name = RFIFOP(fd,2);
+ WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
+ account_name = (char*)RFIFOP(fd,2);
account_name[23] = '\0';
- remove_control_chars(account_name);
+ remove_control_chars((unsigned char *)account_name);
memcpy(WFIFOP(fd,6), account_name, 24);
{
char email[40];
@@ -2295,7 +2337,7 @@ int parse_admin(int fd) {
login_log("'ladmin': Attempt to give an invalid e-mail (account: %s, ip: %s)" RETCODE,
account_name, ip);
} else {
- remove_control_chars(email);
+ remove_control_chars((unsigned char *)email);
i = search_account_index(account_name);
if (i != -1) {
memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
@@ -2318,10 +2360,10 @@ int parse_admin(int fd) {
if (RFIFOREST(fd) < 28 || RFIFOREST(fd) < (28 + RFIFOW(fd,26)))
return 0;
WFIFOW(fd,0) = 0x7943;
- WFIFOL(fd,2) = -1;
- account_name = RFIFOP(fd,2);
+ WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
+ account_name = (char*)RFIFOP(fd,2);
account_name[23] = '\0';
- remove_control_chars(account_name);
+ remove_control_chars((unsigned char *)account_name);
i = search_account_index(account_name);
if (i != -1) {
int size_of_memo = sizeof(auth_dat[i].memo);
@@ -2335,7 +2377,7 @@ int parse_admin(int fd) {
memcpy(auth_dat[i].memo, RFIFOP(fd,28), RFIFOW(fd,26));
}
auth_dat[i].memo[size_of_memo - 1] = '\0';
- remove_control_chars(auth_dat[i].memo);
+ remove_control_chars((unsigned char *)auth_dat[i].memo);
WFIFOL(fd,2) = auth_dat[i].account_id;
login_log("'ladmin': Modification of a memo field (account: %s, new memo: %s, ip: %s)" RETCODE,
auth_dat[i].userid, auth_dat[i].memo, ip);
@@ -2353,10 +2395,10 @@ int parse_admin(int fd) {
if (RFIFOREST(fd) < 26)
return 0;
WFIFOW(fd,0) = 0x7945;
- WFIFOL(fd,2) = -1;
- account_name = RFIFOP(fd,2);
+ WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
+ account_name = (char*)RFIFOP(fd,2);
account_name[23] = '\0';
- remove_control_chars(account_name);
+ remove_control_chars((unsigned char *)account_name);
i = search_account_index(account_name);
if (i != -1) {
memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
@@ -2380,7 +2422,7 @@ int parse_admin(int fd) {
memset(WFIFOP(fd,6), '\0', 24);
for(i = 0; i < auth_num; i++) {
if (auth_dat[i].account_id == RFIFOL(fd,2)) {
- strncpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
+ strncpy((char*)WFIFOP(fd,6), auth_dat[i].userid, 24);
login_log("'ladmin': Request (by id) of an account name (account: %s, id: %d, ip: %s)" RETCODE,
auth_dat[i].userid, RFIFOL(fd,2), ip);
break;
@@ -2389,7 +2431,7 @@ int parse_admin(int fd) {
if (i == auth_num) {
login_log("'ladmin': Name request (by id) of an unknown account (id: %d, ip: %s)" RETCODE,
RFIFOL(fd,2), ip);
- strncpy(WFIFOP(fd,6), "", 24);
+ strncpy((char*)WFIFOP(fd,6), "", 24);
}
WFIFOSET(fd,30);
RFIFOSKIP(fd,6);
@@ -2402,10 +2444,10 @@ int parse_admin(int fd) {
time_t timestamp;
char tmpstr[2048];
WFIFOW(fd,0) = 0x7949;
- WFIFOL(fd,2) = -1;
- account_name = RFIFOP(fd,2);
+ WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
+ account_name = (char*)RFIFOP(fd,2);
account_name[23] = '\0';
- remove_control_chars(account_name);
+ remove_control_chars((unsigned char *)account_name);
timestamp = (time_t)RFIFOL(fd,26);
strftime(tmpstr, 24, date_format, localtime(&timestamp));
i = search_account_index(account_name);
@@ -2434,10 +2476,10 @@ int parse_admin(int fd) {
time_t timestamp;
char tmpstr[2048];
WFIFOW(fd,0) = 0x794b;
- WFIFOL(fd,2) = -1;
- account_name = RFIFOP(fd,2);
+ WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
+ account_name = (char*)RFIFOP(fd,2);
account_name[23] = '\0';
- remove_control_chars(account_name);
+ remove_control_chars((unsigned char *)account_name);
timestamp = (time_t)RFIFOL(fd,26);
if (timestamp <= time(NULL))
timestamp = 0;
@@ -2482,10 +2524,10 @@ int parse_admin(int fd) {
struct tm *tmtime;
char tmpstr[2048];
WFIFOW(fd,0) = 0x794d;
- WFIFOL(fd,2) = -1;
- account_name = RFIFOP(fd,2);
+ WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
+ account_name = (char*)RFIFOP(fd,2);
account_name[23] = '\0';
- remove_control_chars(account_name);
+ remove_control_chars((unsigned char *)account_name);
i = search_account_index(account_name);
if (i != -1) {
WFIFOL(fd,2) = auth_dat[i].account_id;
@@ -2544,7 +2586,7 @@ int parse_admin(int fd) {
if (RFIFOREST(fd) < 8 || RFIFOREST(fd) < (8 + RFIFOL(fd,4)))
return 0;
WFIFOW(fd,0) = 0x794f;
- WFIFOW(fd,2) = -1;
+ WFIFOW(fd,2) = 0xFFFF; // WTF???
if (RFIFOL(fd,4) < 1) {
login_log("'ladmin': Receiving a message for broadcast, but message is void (ip: %s)" RETCODE,
ip);
@@ -2557,13 +2599,13 @@ int parse_admin(int fd) {
login_log("'ladmin': Receiving a message for broadcast, but no char-server is online (ip: %s)" RETCODE,
ip);
} else {
- char buf[32000];
+ unsigned char buf[32000];
char message[32000];
WFIFOW(fd,2) = 0;
memset(message, '\0', sizeof(message));
memcpy(message, RFIFOP(fd,8), RFIFOL(fd,4));
message[sizeof(message)-1] = '\0';
- remove_control_chars(message);
+ remove_control_chars((unsigned char *)message);
if (RFIFOW(fd,2) == 0)
login_log("'ladmin': Receiving a message for broadcast (message (in yellow): %s, ip: %s)" RETCODE,
message, ip);
@@ -2589,10 +2631,10 @@ int parse_admin(int fd) {
char tmpstr[2048];
char tmpstr2[2048];
WFIFOW(fd,0) = 0x7951;
- WFIFOL(fd,2) = -1;
- account_name = RFIFOP(fd,2);
+ WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
+ account_name = (char*)RFIFOP(fd,2);
account_name[23] = '\0';
- remove_control_chars(account_name);
+ remove_control_chars((unsigned char *)account_name);
i = search_account_index(account_name);
if (i != -1) {
WFIFOL(fd,2) = auth_dat[i].account_id;
@@ -2643,10 +2685,10 @@ int parse_admin(int fd) {
if (RFIFOREST(fd) < 26)
return 0;
WFIFOW(fd,0) = 0x7953;
- WFIFOL(fd,2) = -1;
- account_name = RFIFOP(fd,2);
+ WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
+ account_name = (char*)RFIFOP(fd,2);
account_name[23] = '\0';
- remove_control_chars(account_name);
+ remove_control_chars((unsigned char *)account_name);
i = search_account_index(account_name);
if (i != -1) {
WFIFOL(fd,2) = auth_dat[i].account_id;
@@ -2710,7 +2752,7 @@ int parse_admin(int fd) {
if (i == auth_num) {
login_log("'ladmin': Attempt to obtain information (by the id) of an unknown account (id: %d, ip: %s)" RETCODE,
RFIFOL(fd,2), ip);
- strncpy(WFIFOP(fd,7), "", 24);
+ strncpy((char*)WFIFOP(fd,7), "", 24);
WFIFOW(fd,148) = 0;
WFIFOSET(fd,150);
}
@@ -2733,7 +2775,7 @@ int parse_admin(int fd) {
logfp = fopen(login_log_unknown_packets_filename, "a");
if (logfp) {
gettimeofday(&tv, NULL);
- strftime(tmpstr, 23, date_format, localtime(&(tv.tv_sec)));
+ strftime(tmpstr, 23, date_format, localtime((const time_t*)&(tv.tv_sec)));
fprintf(logfp, "%s.%03d: receiving of an unknown packet -> disconnection" RETCODE, tmpstr, (int)tv.tv_usec / 1000);
fprintf(logfp, "parse_admin: connection #%d (ip: %s), packet: 0x%x (with being read: %d)." RETCODE, fd, ip, RFIFOW(fd,0), RFIFOREST(fd));
fprintf(logfp, "Detail (in hex):" RETCODE);
@@ -2809,6 +2851,8 @@ int parse_login(int fd) {
sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+ memset(&account, 0, sizeof(account));
+
if (session[fd]->eof) {
close(fd);
delete_session(fd);
@@ -2826,7 +2870,7 @@ int parse_login(int fd) {
} else
printf("parse_login: connection #%d, packet: 0x%x (with being read: %d).\n", fd, RFIFOW(fd,0), RFIFOREST(fd));
}
-
+
switch(RFIFOW(fd,0)) {
case 0x200: // New alive packet: structure: 0x200 <account.userid>.24B. used to verify if client is always alive.
if (RFIFOREST(fd) < 26)
@@ -2844,10 +2888,11 @@ int parse_login(int fd) {
case 0x01dd: // Ask connection of a client (encryption mode)
if (RFIFOREST(fd) < ((RFIFOW(fd,0) == 0x64) ? 55 : 47))
return 0;
-
- account.userid = RFIFOP(fd,6);
+
+ account.version = RFIFOL(fd, 2); //for exe version check [Sirius]
+ account.userid = (char*)RFIFOP(fd,6);
account.userid[23] = '\0';
- remove_control_chars(account.userid);
+ remove_control_chars((unsigned char *)account.userid);
if (RFIFOW(fd,0) == 0x64) {
memcpy(account.passwd, RFIFOP(fd,30), 24);
account.passwd[24] = '\0';
@@ -2855,7 +2900,7 @@ int parse_login(int fd) {
memcpy(account.passwd, RFIFOP(fd,30), 32);
account.passwd[32] = '\0';
}
- remove_control_chars(account.passwd);
+ remove_control_chars((unsigned char *)account.passwd);
#ifdef PASSWORDENC
account.passwdenc = (RFIFOW(fd,0) == 0x64) ? 0 : PASSWORDENC;
#else
@@ -2901,7 +2946,7 @@ int parse_login(int fd) {
memcpy(WFIFOP(fd,47+server_num*32+6), server[i].name, 20);
WFIFOW(fd,47+server_num*32+26) = server[i].users;
WFIFOW(fd,47+server_num*32+28) = server[i].maintenance;
- WFIFOW(fd,47+server_num*32+30) = server[i].new;
+ WFIFOW(fd,47+server_num*32+30) = server[i].new_;
server_num++;
}
}
@@ -2965,7 +3010,8 @@ int parse_login(int fd) {
session[fd]->eof = 1;
return 0;
}
- ld = session[fd]->session_data = (struct login_session_data*)aCalloc(1, sizeof(struct login_session_data));
+ ld = (struct login_session_data*)aCalloc(1, sizeof(struct login_session_data));
+ session[fd]->session_data = ld;
if (!ld) {
printf("login: Request for md5 key: memory allocation failure (malloc)!\n");
session[fd]->eof = 1;
@@ -2993,17 +3039,17 @@ int parse_login(int fd) {
return 0;
{
int GM_value, len;
- unsigned char* server_name;
- account.userid = RFIFOP(fd,2);
+ char* server_name;
+ account.userid = (char*)RFIFOP(fd,2);
account.userid[23] = '\0';
- remove_control_chars(account.userid);
+ remove_control_chars((unsigned char *)account.userid);
memcpy(account.passwd, RFIFOP(fd,26), 24);
account.passwd[24] = '\0';
- remove_control_chars(account.passwd);
+ remove_control_chars((unsigned char *)account.passwd);
account.passwdenc = 0;
- server_name = RFIFOP(fd,60);
+ server_name = (char*)RFIFOP(fd,60);
server_name[19] = '\0';
- remove_control_chars(server_name);
+ remove_control_chars((unsigned char *)server_name);
login_log("Connection request of the char-server '%s' @ %d.%d.%d.%d:%d (ip: %s)" RETCODE,
server_name, RFIFOB(fd,54), RFIFOB(fd,55), RFIFOB(fd,56), RFIFOB(fd,57), RFIFOW(fd,58), ip);
result = mmo_auth(&account, fd);
@@ -3017,10 +3063,8 @@ int parse_login(int fd) {
memcpy(server[account.account_id].name, server_name, 20);
server[account.account_id].users = 0;
server[account.account_id].maintenance = RFIFOW(fd,82);
- server[account.account_id].new = RFIFOW(fd,84);
+ server[account.account_id].new_ = RFIFOW(fd,84);
server_fd[account.account_id] = fd;
- if(anti_freeze_enable)
- server_freezeflag[account.account_id] = 5; // Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed
WFIFOW(fd,0) = 0x2711;
WFIFOB(fd,2) = 0;
WFIFOSET(fd,3);
@@ -3042,10 +3086,8 @@ int parse_login(int fd) {
if (server_fd[account.account_id] != -1) {
printf("Connection of the char-server '%s' REFUSED - already connected (account: %ld-%s, pass: %s, ip: %s)\n",
server_name, account.account_id, account.userid, account.passwd, ip);
- printf("You must probably wait that the freeze system detect the disconnection.\n");
login_log("Connexion of the char-server '%s' REFUSED - already connected (account: %ld-%s, pass: %s, ip: %s)" RETCODE,
server_name, account.account_id, account.userid, account.passwd, ip);
- login_log("You must probably wait that the freeze system detect the disconnection." RETCODE);
} else {
printf("Connection of the char-server '%s' REFUSED (account: %s, pass: %s, ip: %s).\n", server_name, account.userid, account.passwd, ip);
login_log("Connexion of the char-server '%s' REFUSED (account: %s, pass: %s, ip: %s)" RETCODE,
@@ -3086,12 +3128,12 @@ int parse_login(int fd) {
if (!check_ladminip(session[fd]->client_addr.sin_addr.s_addr)) {
login_log("'ladmin'-login: Connection in administration mode refused: IP isn't authorised (ladmin_allow, ip: %s)." RETCODE, ip);
} else {
- struct login_session_data *ld = session[fd]->session_data;
+ struct login_session_data *ld = (struct login_session_data*)session[fd]->session_data;
if (RFIFOW(fd,2) == 0) { // non encrypted password
- unsigned char* password="";
+ char* password="";
memcpy(password, RFIFOP(fd,4), 24);
password[24] = '\0';
- remove_control_chars(password);
+ remove_control_chars((unsigned char *)password);
// If remote administration is enabled and password sent by client matches password read from login server configuration file
if ((admin_state == 1) && (strcmp(password, admin_pass) == 0)) {
login_log("'ladmin'-login: Connection in administration mode accepted (non encrypted password: %s, ip: %s)" RETCODE, password, ip);
@@ -3138,7 +3180,7 @@ int parse_login(int fd) {
logfp = fopen(login_log_unknown_packets_filename, "a");
if (logfp) {
gettimeofday(&tv, NULL);
- strftime(tmpstr, 23, date_format, localtime(&(tv.tv_sec)));
+ strftime(tmpstr, 23, date_format, localtime((const time_t*)&(tv.tv_sec)));
fprintf(logfp, "%s.%03d: receiving of an unknown packet -> disconnection" RETCODE, tmpstr, (int)tv.tv_usec / 1000);
fprintf(logfp, "parse_login: connection #%d (ip: %s), packet: 0x%x (with being read: %d)." RETCODE, fd, ip, RFIFOW(fd,0), RFIFOREST(fd));
fprintf(logfp, "Detail (in hex):" RETCODE);
@@ -3186,9 +3228,9 @@ int parse_console(char *buf) {
char command[256];
memset(command,0,sizeof(command));
-
+
sscanf(buf, "%[^\n]", command);
-
+
login_log("Console command :%s" RETCODE, command);
if(strcmpi("shutdown", command) == 0 ||
@@ -3260,8 +3302,8 @@ int login_lan_config_read(const char *lancfgName) {
if (sscanf(line,"%[^:]: %[^\r\n]", w1, w2) != 2)
continue;
- remove_control_chars(w1);
- remove_control_chars(w2);
+ remove_control_chars((unsigned char *)w1);
+ remove_control_chars((unsigned char *)w2);
if (strcmpi(w1, "lan_char_ip") == 0) { // Read Char-Server Lan IP Address
memset(lan_char_ip, 0, sizeof(lan_char_ip));
h = gethostbyname(w2);
@@ -3328,6 +3370,9 @@ int login_lan_config_read(const char *lancfgName) {
int login_config_read(const char *cfgName) {
char line[1024], w1[1024], w2[1024];
FILE *fp;
+ struct hostent *h = NULL;
+
+ bind_ip_str[0] = '\0';
if ((fp = fopen(cfgName, "r")) == NULL) {
printf("Configuration file (%s) not found.\n", cfgName);
@@ -3342,8 +3387,8 @@ int login_config_read(const char *cfgName) {
line[sizeof(line)-1] = '\0';
memset(w2, 0, sizeof(w2));
if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2) {
- remove_control_chars(w1);
- remove_control_chars(w2);
+ remove_control_chars((unsigned char *)w1);
+ remove_control_chars((unsigned char *)w2);
if (strcmpi(w1, "admin_state") == 0) {
admin_state = config_switch(w2);
@@ -3353,22 +3398,22 @@ int login_config_read(const char *cfgName) {
admin_pass[sizeof(admin_pass)-1] = '\0';
} else if (strcmpi(w1, "ladminallowip") == 0) {
if (strcmpi(w2, "clear") == 0) {
- if (access_ladmin_allow)
- free(access_ladmin_allow);
+ if (access_ladmin_allow)
+ aFree(access_ladmin_allow);
access_ladmin_allow = NULL;
access_ladmin_allownum = 0;
} else {
if (strcmpi(w2, "all") == 0) {
// reset all previous values
if (access_ladmin_allow)
- free(access_ladmin_allow);
+ aFree(access_ladmin_allow);
// set to all
access_ladmin_allow = (char*)aCalloc(ACO_STRSIZE, sizeof(char));
access_ladmin_allownum = 1;
access_ladmin_allow[0] = '\0';
} else if (w2[0] && !(access_ladmin_allownum == 1 && access_ladmin_allow[0] == '\0')) { // don't add IP if already 'all'
if (access_ladmin_allow)
- access_ladmin_allow = realloc(access_ladmin_allow, (access_ladmin_allownum+1) * ACO_STRSIZE);
+ access_ladmin_allow = (char*)aRealloc(access_ladmin_allow, (access_ladmin_allownum+1) * ACO_STRSIZE);
else
access_ladmin_allow = (char*)aCalloc(ACO_STRSIZE, sizeof(char));
strncpy(access_ladmin_allow + (access_ladmin_allownum++) * ACO_STRSIZE, w2, ACO_STRSIZE);
@@ -3383,6 +3428,14 @@ int login_config_read(const char *cfgName) {
level_new_gm = atoi(w2);
} else if (strcmpi(w1, "new_account") == 0) {
new_account_flag = config_switch(w2);
+ } else if (strcmpi(w1, "bind_ip") == 0) {
+ //bind_ip_set_ = 1;
+ h = gethostbyname (w2);
+ if (h != NULL) {
+ printf("Login server binding IP address : %s -> %d.%d.%d.%d\n", w2, (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+ sprintf(bind_ip_str, "%d.%d.%d.%d", (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+ } else
+ memcpy(bind_ip_str,w2,16);
} else if (strcmpi(w1, "login_port") == 0) {
login_port = atoi(w2);
} else if (strcmpi(w1, "account_filename") == 0) {
@@ -3401,6 +3454,8 @@ int login_config_read(const char *cfgName) {
memset(login_log_filename, 0, sizeof(login_log_filename));
strncpy(login_log_filename, w2, sizeof(login_log_filename));
login_log_filename[sizeof(login_log_filename)-1] = '\0';
+ } else if (strcmpi(w1, "log_login") == 0) {
+ log_login = atoi(w2);
} else if (strcmpi(w1, "login_log_unknown_packets_filename") == 0) {
memset(login_log_unknown_packets_filename, 0, sizeof(login_log_unknown_packets_filename));
strncpy(login_log_unknown_packets_filename, w2, sizeof(login_log_unknown_packets_filename));
@@ -3448,21 +3503,21 @@ int login_config_read(const char *cfgName) {
} else if (strcmpi(w1, "allow") == 0) {
if (strcmpi(w2, "clear") == 0) {
if (access_allow)
- free(access_allow);
+ aFree(access_allow);
access_allow = NULL;
access_allownum = 0;
} else {
if (strcmpi(w2, "all") == 0) {
// reset all previous values
if (access_allow)
- free(access_allow);
+ aFree(access_allow);
// set to all
access_allow = (char*)aCalloc(ACO_STRSIZE, sizeof(char));
access_allownum = 1;
access_allow[0] = '\0';
} else if (w2[0] && !(access_allownum == 1 && access_allow[0] == '\0')) { // don't add IP if already 'all'
if (access_allow)
- access_allow = realloc(access_allow, (access_allownum+1) * ACO_STRSIZE);
+ access_allow = (char*)aRealloc(access_allow, (access_allownum+1) * ACO_STRSIZE);
else
access_allow = (char*)aCalloc(ACO_STRSIZE, sizeof(char));
strncpy(access_allow + (access_allownum++) * ACO_STRSIZE, w2, ACO_STRSIZE);
@@ -3472,21 +3527,21 @@ int login_config_read(const char *cfgName) {
} else if (strcmpi(w1, "deny") == 0) {
if (strcmpi(w2, "clear") == 0) {
if (access_deny)
- free(access_deny);
+ aFree(access_deny);
access_deny = NULL;
access_denynum = 0;
} else {
if (strcmpi(w2, "all") == 0) {
// reset all previous values
if (access_deny)
- free(access_deny);
+ aFree(access_deny);
// set to all
access_deny = (char*)aCalloc(ACO_STRSIZE, sizeof(char));
access_denynum = 1;
access_deny[0] = '\0';
} else if (w2[0] && !(access_denynum == 1 && access_deny[0] == '\0')) { // don't add IP if already 'all'
if (access_deny)
- access_deny = realloc(access_deny, (access_denynum+1) * ACO_STRSIZE);
+ access_deny = (char*)aRealloc(access_deny, (access_denynum+1) * ACO_STRSIZE);
else
access_deny = (char*)aCalloc(ACO_STRSIZE, sizeof(char));
strncpy(access_deny + (access_denynum++) * ACO_STRSIZE, w2, ACO_STRSIZE);
@@ -3502,13 +3557,6 @@ int login_config_read(const char *cfgName) {
dynamic_pass_failure_ban_how_many = atoi(w2);
} else if (strcmpi(w1, "dynamic_pass_failure_ban_how_long") == 0) {
dynamic_pass_failure_ban_how_long = atoi(w2);
- // Anti-Freeze
- } else if(strcmpi(w1,"anti_freeze_enable")==0){
- anti_freeze_enable = config_switch(w2);
- } else if (strcmpi(w1, "anti_freeze_interval") == 0) {
- ANTI_FREEZE_INTERVAL = atoi(w2);
- if (ANTI_FREEZE_INTERVAL < 5)
- ANTI_FREEZE_INTERVAL = 5; // minimum 5 seconds
} else if (strcmpi(w1, "import") == 0) {
login_config_read(w2);
} else if(strcmpi(w1,"imalive_on")==0) { //Added by Mugendai for I'm Alive mod
@@ -3519,6 +3567,15 @@ int login_config_read(const char *cfgName) {
flush_on = atoi(w2); //Added by Mugendai for GUI
} else if(strcmpi(w1,"flush_time")==0) { //Added by Mugendai for GUI
flush_time = atoi(w2); //Added by Mugendai for GUI
+ } else if(strcmpi(w1, "check_client_version") == 0){ //Added by Sirius for client version check
+ if(strcmpi(w2,"on") == 0 || strcmpi(w2,"yes") == 0 ){
+ check_client_version = 1;
+ }
+ if(strcmpi(w2,"off") == 0 || strcmpi(w2,"no") == 0 ){
+ check_client_version = 0;
+ }
+ }else if(strcmpi(w1, "client_version_to_connect") == 0){ //Added by Sirius for client version check
+ client_version_to_connect = atoi(w2); //Added by Sirius for client version check
} else if (strcmpi(w1, "console") == 0) {
if(strcmpi(w2,"on") == 0 || strcmpi(w2,"yes") == 0 )
console = 1;
@@ -3850,32 +3907,42 @@ int flush_timer(int tid, unsigned int tick, int id, int data){
//--------------------------------------
// Function called at exit of the server
//--------------------------------------
+static int online_db_final(void *key,void *data,va_list ap)
+{
+ int *p = (int *) data;
+ if (p) aFree(p);
+ return 0;
+}
void do_final(void) {
int i, fd;
-
+ printf("Terminating...\n");
+ fflush(stdout);
mmo_auth_sync();
+ numdb_final(online_db, online_db_final);
- if(auth_dat) free(auth_dat);
- if(gm_account_db) free(gm_account_db);
- if(access_ladmin_allow) free(access_ladmin_allow);
- if(access_allow) free(access_allow);
- if(access_deny) free(access_deny);
+ if(auth_dat) aFree(auth_dat);
+ if(gm_account_db) aFree(gm_account_db);
+ if(access_ladmin_allow) aFree(access_ladmin_allow);
+ if(access_allow) aFree(access_allow);
+ if(access_deny) aFree(access_deny);
for (i = 0; i < MAX_SERVERS; i++) {
if ((fd = server_fd[i]) >= 0) {
server_fd[i] = -1;
memset(&server[i], 0, sizeof(struct mmo_char_server));
close(fd);
delete_session(fd);
- if(session[fd]->session_data) free(session[fd]->session_data);
}
}
close(login_fd);
delete_session(login_fd);
+ exit_dbn();
+ timer_final();
login_log("----End of login-server (normal end with closing of all files)." RETCODE);
if(log_fp)
fclose(log_fp);
+ printf("Finished.\n");
}
//------------------------------
@@ -3884,6 +3951,7 @@ void do_final(void) {
int do_init(int argc, char **argv) {
int i, j;
+ SERVER_TYPE = SERVER_LOGIN;
// read login-server configuration
login_config_read((argc > 1) ? argv[1] : LOGIN_CONF_NAME);
display_conf_warnings(); // not in login_config_read, because we can use 'import' option, and display same message twice or more
@@ -3905,12 +3973,17 @@ int do_init(int argc, char **argv) {
read_gm_account();
// set_termfunc(mmo_auth_sync);
set_defaultparse(parse_login);
- login_fd = make_listen_port(login_port);
-
- if(anti_freeze_enable > 0) {
- add_timer_func_list(char_anti_freeze_system, "char_anti_freeze_system");
- i = add_timer_interval(gettick() + 1000, char_anti_freeze_system, 0, 0, ANTI_FREEZE_INTERVAL * 1000);
- }
+ // Online user database init
+ online_db = numdb_init();
+
+ if (bind_ip_str[0] != '\0')
+ bind_ip = inet_addr(bind_ip_str);
+ else
+ bind_ip = INADDR_ANY;
+
+ //login_fd = make_listen_port(login_port);
+ login_fd = make_listen_bind(bind_ip,login_port);
+
add_timer_func_list(check_auth_sync, "check_auth_sync");
i = add_timer_interval(gettick() + 60000, check_auth_sync, 0, 0, 60000); // every 60 sec we check if we must save accounts file (only if necessary to save)
@@ -3934,7 +4007,7 @@ int do_init(int argc, char **argv) {
set_defaultconsoleparse(parse_console);
start_console();
}
-
+
login_log("The login-server is ready (Server is listening on the port %d)." RETCODE, login_port);
printf("The login-server is \033[1;32mready\033[0m (Server is listening on the port %d).\n\n", login_port);
diff --git a/src/login/login.h b/src/login/login.h
index 9ae4734fe..c08952383 100644
--- a/src/login/login.h
+++ b/src/login/login.h
@@ -13,8 +13,9 @@
#define START_ACCOUNT_NUM 2000000
#define END_ACCOUNT_NUM 100000000
-int login_port;
+extern int login_port;
struct mmo_account {
+ int version; //Added for version check [Sirius]
char* userid;
char passwd[33];
int passwdenc;
@@ -33,9 +34,9 @@ struct mmo_char_server {
short port;
int users;
int maintenance;
- int new;
+ int new_;
};
-struct mmo_char_server server[MAX_SERVERS];
-int server_fd[MAX_SERVERS];
+extern struct mmo_char_server server[MAX_SERVERS];
+extern int server_fd[MAX_SERVERS];
#endif
diff --git a/src/login/md5calc.c b/src/login/md5calc.c
index 96bfc34d0..0ee64476d 100644
--- a/src/login/md5calc.c
+++ b/src/login/md5calc.c
@@ -96,7 +96,7 @@ static void MD5_Round_Calculate(const unsigned char *block,
//Save A as AA, B as BB, C as CC, and and D as DD (saving of A, B, C, and D)
unsigned int A=*A2, B=*B2, C=*C2, D=*D2;
unsigned int AA = A,BB = B,CC = C,DD = D;
-
+
//It is a large region variable reluctantly because of calculation of a round. . . for Round1...4
pX = X;
@@ -187,7 +187,7 @@ void MD5_String2binary(const char * string, char * output)
memset(padding_message+copy_len, 0, 64 - copy_len); //It buries by 0 until it becomes extended bit length.
padding_message[copy_len] |= 0x80; //The next of a message is 1.
- //1-4
+ //1-4
//If 56 bytes or more (less than 64 bytes) of remainder becomes, it will calculate by extending to 64 bytes.
if (56 <= copy_len) {
MD5_Round_Calculate(padding_message, A,B,C,D);
@@ -226,7 +226,7 @@ void MD5_String(const char * string, char * output)
{
unsigned char digest[16];
- MD5_String2binary(string,digest);
+ MD5_String2binary(string,(char*)digest);
sprintf(output,
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
digest[ 0], digest[ 1], digest[ 2], digest[ 3],
diff --git a/src/login_sql/GNUmakefile b/src/login_sql/GNUmakefile
deleted file mode 100644
index e941469e1..000000000
--- a/src/login_sql/GNUmakefile
+++ /dev/null
@@ -1,18 +0,0 @@
-all: login-server_sql
-sql: login-server_sql
-
-shared_libs=all
-COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o ../common/malloc.o ../common/showmsg.o ../common/nullpo.o
-COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/db.h ../common/malloc.h ../common/showmsg.h ../common/nullpo.h
-
-login-server_sql: login.o char_int.o login_int.o md5calc.o strlib.o $(COMMON_OBJ)
- $(CC) -o ../../$@ $^ $(LIB_S)
-
-login.o: login.c login.h md5calc.h strlib.h char_int.h login_int.h $(COMMON_H)
-char_int.o: char_int.c login.h char_int.h $(COMMON_H)
-login_int.o: login_int.c login.h login_int.h char_int.h $(COMMON_H)
-md5calc.o: md5calc.c md5calc.h
-strlib.o: strlib.c strlib.h
-
-clean:
- rm -f *.o ../../login-server_sql \ No newline at end of file
diff --git a/src/login_sql/Makefile b/src/login_sql/Makefile
index e941469e1..20b01c66d 100644
--- a/src/login_sql/Makefile
+++ b/src/login_sql/Makefile
@@ -2,17 +2,15 @@ all: login-server_sql
sql: login-server_sql
shared_libs=all
-COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o ../common/malloc.o ../common/showmsg.o ../common/nullpo.o
-COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/db.h ../common/malloc.h ../common/showmsg.h ../common/nullpo.h
+COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o ../common/obj/db.o ../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/strlib.o
+COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/db.h ../common/malloc.h ../common/showmsg.h ../common/strlib.h
-login-server_sql: login.o char_int.o login_int.o md5calc.o strlib.o $(COMMON_OBJ)
+login-server_sql: login.o md5calc.o $(COMMON_OBJ)
$(CC) -o ../../$@ $^ $(LIB_S)
-login.o: login.c login.h md5calc.h strlib.h char_int.h login_int.h $(COMMON_H)
-char_int.o: char_int.c login.h char_int.h $(COMMON_H)
-login_int.o: login_int.c login.h login_int.h char_int.h $(COMMON_H)
+login.o: login.c login.h md5calc.h $(COMMON_H)
md5calc.o: md5calc.c md5calc.h
-strlib.o: strlib.c strlib.h
clean:
- rm -f *.o ../../login-server_sql \ No newline at end of file
+ rm -f *.o ../../login-server_sql
+
diff --git a/src/login_sql/char_int.c b/src/login_sql/char_int.c
deleted file mode 100644
index 30153737a..000000000
--- a/src/login_sql/char_int.c
+++ /dev/null
@@ -1,512 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include "login.h"
-
-//--------------------------------
-// Send to char
-//--------------------------------
-int charif_sendallwos(int sfd, unsigned char *buf, unsigned int len) {
- int i, c;
- int fd;
-
- c = 0;
- for(i = 0; i < MAX_SERVERS && i < servers_connected; i++) {
- if ((fd = server_fd[i]) > 0 && fd != sfd) {
- memcpy(WFIFOP(fd,0), buf, len);
- WFIFOSET(fd,len);
- c++;
- }
- }
-
- return c;
-}
-
-//--------------------------------
-// Char-server anti-freeze system
-//--------------------------------
-int char_anti_freeze_system(int tid, unsigned int tick, int id, int data) {
- int i;
-
- for(i = 0; i < MAX_SERVERS && i < servers_connected; i++) {
- if (server_fd[i] >= 0) {// if char-server is online
-// printf("char_anti_freeze_system: server #%d '%s', flag: %d.\n", i, server[i].name, server_freezeflag[i]);
- if (server_freezeflag[i]-- < 1) {// Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed
- session[server_fd[i]]->eof = 1;
- }
- }
- }
-
- return 0;
-}
-
-//-------------------------------------------
-// Request for account reg from char-server [Edit: Wizputer]
-//-------------------------------------------
-int send_account_reg(int fd, int len) {
- if (RFIFOREST(fd) < 19)
- return -1;
-
- int account_id = RFIFOL(fd,2);
- int i;
-
- for(i=0;i<AUTH_FIFO_SIZE;i++){
- if (auth_fifo[i].account_id == account_id &&
- auth_fifo[i].login_id1 == RFIFOL(fd,6) &&
-#if CMP_AUTHFIFO_LOGIN2 != 0
- auth_fifo[i].login_id2 == RFIFOL(fd,10) && // relate to the versions higher than 18
-#endif
- auth_fifo[i].sex == RFIFOB(fd,14) &&
-#if CMP_AUTHFIFO_IP != 0
- auth_fifo[i].ip == RFIFOL(fd,15) &&
-#endif
- !auth_fifo[i].delflag) {
- auth_fifo[i].delflag = 1;
- #ifdef DEBUG
- printf("Client: [%d] Auth Number: [%d]\n",fd, i);
- #endif
- break;
- }
- }
-
- if (i != AUTH_FIFO_SIZE) { // send account_reg
- int p;
- time_t connect_until_time = 0;
- char email[40] = "";
-
- sprintf(tmpsql, "SELECT `email`,`connect_until` FROM `%s` WHERE `%s`='%d'", login_db, login_db_account_id, account_id);
- sql_query(tmpsql,"send_account_reg");
-
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
- if((sql_row = mysql_fetch_row(sql_res))) {
- connect_until_time = atol(sql_row[1]);
- strcpy(email, sql_row[0]);
- }
- }
- mysql_free_result(sql_res);
-
- if (account_id > 0) {
- sprintf(tmpsql, "SELECT `str`,`value` FROM `global_reg_value` WHERE `type`='1' AND `account_id`='%d'",account_id);
- sql_query(tmpsql,"send_account_reg");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
- WFIFOW(fd,0) = 0x2729;
- WFIFOL(fd,4) = account_id;
- for(p = 8; (sql_row = mysql_fetch_row(sql_res));p+=36){
- memcpy(WFIFOP(fd,p), sql_row[0], 32);
- WFIFOL(fd,p+32) = atoi(sql_row[1]);
- }
- WFIFOW(fd,2) = p;
- WFIFOSET(fd,p);
- #ifdef DEBUG
- printf("account_reg2 send : login->char (auth fifo)\n");
- #endif
- WFIFOW(fd,0) = 0x2713;
- WFIFOL(fd,2) = account_id;
- WFIFOB(fd,6) = 0;
- memcpy(WFIFOP(fd, 7), email, 40);
- WFIFOL(fd,47) = (unsigned long) connect_until_time;
- WFIFOSET(fd,51);
- }
- mysql_free_result(sql_res);
- }
- } else {
- WFIFOW(fd,0) = 0x2713;
- WFIFOL(fd,2) = account_id;
- WFIFOB(fd,6) = 1;
- WFIFOSET(fd,51);
- }
- RFIFOSKIP(fd,19);
-
- return 0;
-}
-
-//----------------------------------------------------------
-// Number of users in the world (connected char-server(s)) [Edit: Wizputer]
-//----------------------------------------------------------
-int number_world_users(int fd, int len, int id) {
- if (len < 6)
- return -1;
-
- #ifdef DEBUG
- if (server[id].users != RFIFOL(fd,2))
- printf("set number users %s : %d\n", server[id].name, RFIFOL(fd,2));
- #endif
-
- server[id].users = RFIFOL(fd,2);
- if(anti_freeze_enable)
- server_freezeflag[id] = 5; // Char anti-freeze system. Counter. 5 ok, 4...0 freezed
-
- sprintf(tmpsql,"UPDATE `sstatus` SET `user` = '%d' WHERE `index` = '%d'", server[id].users, id);
- sql_query(tmpsql,"number_world_users");
-
- RFIFOSKIP(fd,6);
-
- return 0;
-}
-
-//-----------------------------------------
-// Email and Time request from char-server [Edit: Wizputer]
-//-----------------------------------------
-int email_time_request(int fd, int len, int id) {
- if (len < 6)
- return -1;
-
- int account_id=RFIFOL(fd,2);
- time_t connect_until_time = 0;
- char email[40] = "";
-
- sprintf(tmpsql,"SELECT `email`,`connect_until` FROM `%s` WHERE `%s`='%d'",login_db, login_db_account_id, account_id);
- sql_query(tmpsql,"email_time_request");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
- if((sql_row = mysql_fetch_row(sql_res))) {
- connect_until_time = atol(sql_row[1]);
- strcpy(email, sql_row[0]);
- }
- }
- mysql_free_result(sql_res);
-
- #ifdef DEBUG
- printf("parse_fromchar: E-mail/limited time request from '%s' server (concerned account: %d)\n", server[id].name, account_id);
- #endif
-
- WFIFOW(fd,0) = 0x2717;
- WFIFOL(fd,2) = account_id;
- memcpy(WFIFOP(fd, 6), email, 40);
- WFIFOL(fd,46) = (unsigned long) connect_until_time;
- WFIFOSET(fd,50);
-
- RFIFOSKIP(fd,6);
-
- return 0;
-}
-
-//--------------------------------
-// Request to change email [Edit: Wizputer]
-//--------------------------------
-int change_account_email(int fd, int len, int id, char ip[16]) {
- if (len < 86)
- return -1;
-
- int acc = RFIFOL(fd,2);
- char actual_email[40], new_email[40];
-
- memcpy(actual_email, RFIFOP(fd,6), 40);
- memcpy(new_email, RFIFOP(fd,46), 40);
-
- if (e_mail_check(actual_email) == 0) {
- #ifdef DEBUG
- printf("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual email is invalid (account: %d, ip: %s)" RETCODE,
- server[id].name, acc, ip);
- #endif
- } else if (e_mail_check(new_email) == 0) {
- #ifdef DEBUG
- printf("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a invalid new e-mail (account: %d, ip: %s)" RETCODE,
- server[id].name, acc, ip);
- #endif
- } else if (strcmpi(new_email, "athena@athena.com") == 0) {
- #ifdef DEBUG
- printf("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a default e-mail (account: %d, ip: %s)" RETCODE,
- server[id].name, acc, ip);
- #endif
- } else {
- sprintf(tmpsql, "SELECT `%s`,`email` FROM `%s` WHERE `%s` = '%d'", login_db_userid, login_db, login_db_account_id, acc);
- sql_query(tmpsql,"change_account_email");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
- if((sql_row = mysql_fetch_row(sql_res))) { //row fetching
- if (strcmpi(sql_row[1], actual_email) == 0) {
- sprintf(tmpsql, "UPDATE `%s` SET `email` = '%s' WHERE `%s` = '%d'", login_db, new_email, login_db_account_id, acc);
- sql_query(tmpsql,"change_account_email");
-
- #ifdef DEBUG
- printf("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s)." RETCODE,
- server[id].name, acc, sql_row[0], actual_email, ip);
- #endif
- }
- }
- }
-
- }
-
- RFIFOSKIP(fd, 86);
-
- return 0;
-}
-
-//-----------------------------------------------
-// State change request from map server (By Yor) [Edit: Wizputer]
-//-----------------------------------------------
-int status_change_request(int fd, int len) {
- if (len < 10)
- return -1;
-
- int acc = RFIFOL(fd,2), status = RFIFOL(fd,6);
-
- sprintf(tmpsql, "SELECT `state` FROM `%s` WHERE `%s` = '%d'", login_db, login_db_account_id, acc);
- sql_query(tmpsql,"status_change_request");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
- if((sql_row = mysql_fetch_row(sql_res))) { // row fetching
- if (atoi(sql_row[0]) != status && status != 0) {
- unsigned char buf[16];
- WBUFW(buf,0) = 0x2731;
- WBUFL(buf,2) = acc;
- WBUFB(buf,6) = 0; // 0: change of statut, 1: ban
- WBUFL(buf,7) = status; // status or final date of a banishment
- charif_sendallwos(-1, buf, 11);
- }
- }
-
- sprintf(tmpsql,"UPDATE `%s` SET `state` = '%d' WHERE `%s` = '%d'", login_db, status,login_db_account_id,acc);
- sql_query(tmpsql,"status_change_request");
- }
-
- RFIFOSKIP(fd,10);
-
- return 0;
-}
-//--------------------------------------
-// Ban request from map-server (By Yor) [Edit: Wizputer]
-//--------------------------------------
-int ban_request(int fd, int len) {
- if (len < 18)
- return -1;
-
- int acc=RFIFOL(fd,2);
- struct tm *tmtime;
- time_t timestamp, tmptime;
-
- sprintf(tmpsql, "SELECT `ban_until` FROM `%s` WHERE `%s` = '%d'",login_db,login_db_account_id,acc);
- sql_query(tmpsql,"ban_request");
-
- if ((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res))) {
- tmptime = atol(sql_row[0]);
-
- if (tmptime == 0 || tmptime < time(NULL))
- timestamp = time(NULL);
- else
- timestamp = tmptime;
-
- tmtime = localtime(&timestamp);
- tmtime->tm_year = tmtime->tm_year + (short)RFIFOW(fd,6);
- tmtime->tm_mon = tmtime->tm_mon + (short)RFIFOW(fd,8);
- tmtime->tm_mday = tmtime->tm_mday + (short)RFIFOW(fd,10);
- tmtime->tm_hour = tmtime->tm_hour + (short)RFIFOW(fd,12);
- tmtime->tm_min = tmtime->tm_min + (short)RFIFOW(fd,14);
- tmtime->tm_sec = tmtime->tm_sec + (short)RFIFOW(fd,16);
-
- timestamp = mktime(tmtime);
-
- if (timestamp != -1) {
- if (timestamp <= time(NULL))
- timestamp = 0;
- if (tmptime != timestamp) {
- if (timestamp != 0) {
- unsigned char buf[16];
- WBUFW(buf,0) = 0x2731;
- WBUFL(buf,2) = acc;
- WBUFB(buf,6) = 1; // 0: change of statut, 1: ban
- WBUFL(buf,7) = timestamp; // status or final date of a banishment
- charif_sendallwos(-1, buf, 11);
- }
- #ifdef DEBUG
- printf("Account: [%d] Banned until: [%ld]\n", acc, timestamp);
- #endif
-
- sprintf(tmpsql, "UPDATE `%s` SET `ban_until` = '%ld', `state`='7' WHERE `%s` = '%d'", login_db, timestamp, login_db_account_id, acc);
- sql_query(tmpsql,"ban_request");
- }
- }
- }
-
- RFIFOSKIP(fd,18);
-
- return 0;
-}
-
-//-----------------------------
-// Change sex [Edit: Wizputer]
-//-----------------------------
-int change_sex(int fd,int len) {
- if (len < 6)
- return -1;
-
- int sex,acc=RFIFOL(fd,4);
- unsigned char buf[16];
-
- sprintf(tmpsql,"SELECT `sex` FROM `%s` WHERE `%s` = '%d'",login_db,login_db_account_id,acc);
- sql_query(tmpsql,"change_sex");
-
- if ((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res))) {
- if (strcmpi(sql_row[0], "M") == 0)
- sex = 1;
- else
- sex = 0;
-
- sprintf(tmpsql,"UPDATE `%s` SET `sex` = '%c' WHERE `%s` = '%d'", login_db, (sex==0?'M':'F'), login_db_account_id, acc);
- sql_query(tmpsql,"change_sex");
-
- WBUFW(buf,0) = 0x2723;
- WBUFL(buf,2) = acc;
- WBUFB(buf,6) = sex;
- charif_sendallwos(-1, buf, 7);
- }
-
- RFIFOSKIP(fd,6);
-
- return 0;
-}
-
-//-------------------------------
-// Save Account Reg [Edit: Wizputer]
-//-------------------------------
-int save_account_reg(int fd, int len){
- if (len < 4 || len < RFIFOW(fd,2))
- return -1;
-
- int p,j,value,acc=RFIFOL(fd,4);
- char str[32];
- char temp_str[32];
-
- if (acc>0){
- unsigned char buf[RFIFOW(fd,2)+1];
- for(p=8,j=0;p<RFIFOW(fd,2) && j<ACCOUNT_REG2_NUM;p+=36,j++){
- memcpy(str,RFIFOP(fd,p),32);
- value=RFIFOL(fd,p+32);
-
- sprintf(tmpsql,"REPLACE INTO `global_reg_value` (`type`, `account_id`, `str`, `value`) VALUES ( 1 , '%d' , '%s' , '%d');", acc, jstrescapecpy(temp_str,str), value);
- sql_query(tmpsql,"save_account_reg");
- }
-
- // Send to char
- memcpy(WBUFP(buf,0),RFIFOP(fd,0),RFIFOW(fd,2));
- WBUFW(buf,0)=0x2729;
- charif_sendallwos(fd,buf,WBUFW(buf,2));
- }
-
- RFIFOSKIP(fd,RFIFOW(fd,2));
-
- #ifdef DEBUG
- printf("login: save account_reg (from char)\n");
- #endif
-
- return 0;
-}
-
-//------------------------------------------------
-// Recieve unban request from map-server (by Yor) [Edit: Wizputer]
-//------------------------------------------------
-int unban_request(int fd, int len) {
- if (len < 6)
- return -1;
-
- int acc = RFIFOL(fd,2);
-
- sprintf(tmpsql,"UPDATE `%s` SET `ban_until` = '0', `state`='0' WHERE `%s` = '%d' AND `state`='6'", login_db,login_db_account_id,acc);
- sql_query(tmpsql,"unban_request");
-
- RFIFOSKIP(fd,6);
-
- return 0;
-}
-
-//---------------------------------------
-// Map-server Add Online User [Wizputer]
-//---------------------------------------
-int map_add_online_user(int fd, int len) {
- if (len < 6)
- return -1;
-
- add_online_user(RFIFOL(fd,2));
-
- RFIFOSKIP(fd,6);
-
- return 0;
-}
-
-//---------------------------------------
-// Map-server Remove Online User [Wizputer]
-//---------------------------------------
-int map_rem_online_user(int fd, int len) {
- if (len < 6)
- return -1;
-
- remove_online_user(RFIFOL(fd,2));
-
- RFIFOSKIP(fd,6);
-
- return 0;
-}
-
-//-----------------------------------------------------
-// char-server packet parse [Edit: Wizputer]
-//-----------------------------------------------------
-int parse_fromchar(int fd){
- int id, len, res=0;
-
- unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
- char ip[16];
-
- sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
-
- for(id = 0; id < MAX_SERVERS && id < servers_connected; id++)
- if (server_fd[id] == fd)
- break;
-
- if (id == MAX_SERVERS)
- session[fd]->eof = 1;
-
- if(session[fd]->eof) {
- if (id < MAX_SERVERS) {
- printf("Char-server '%s' has disconnected.\n", server[id].name);
- server_fd[id] = -1;
- memset(&server[id], 0, sizeof(struct mmo_char_server));
- servers_connected--;
- // server delete
- sprintf(tmpsql, "DELETE FROM `sstatus` WHERE `index`='%d'", id);
- sql_query(tmpsql,"parse_fromchar");
- }
- close(fd);
- delete_session(fd);
- return 0;
- }
-
- len = RFIFOREST(fd);
-
- while(len >= 2 && res == 0) {
- #ifdef DEBUG_PACKETS
- printf("char_parse: %d %d packet case=%x\n", fd, RFIFOREST(fd), RFIFOW(fd, 0));
- #endif
-
- switch (RFIFOW(fd,0)) {
- case 0x2712: res = send_account_reg(fd,len); break;
- case 0x2714: res = number_world_users(fd,len,id); break;
- case 0x2716: res = email_time_request(fd,len,id); break;
- case 0x2722: res = change_account_email(fd,len,id,ip); break;
- case 0x2724: res = status_change_request(fd,len); break;
- case 0x2725: res = ban_request(fd,len); break;
- case 0x2727: res = change_sex(fd,len); break;
- case 0x2728: res = save_account_reg(fd,len); break;
- case 0x272a: res = unban_request(fd,len); break;
- case 0x272b: res = map_add_online_user(fd,len); break;
- case 0x272c: res = map_rem_online_user(fd,len); break;
-
- default:
- #ifdef DEBUG
- printf("login: unknown packet %x! (from char).\n", RFIFOW(fd,0));
- #endif
- session[fd]->eof = 1;
- }
-
- len = RFIFOREST(fd);
- }
-
- return 0;
-}
diff --git a/src/login_sql/char_int.h b/src/login_sql/char_int.h
deleted file mode 100644
index 195d1be42..000000000
--- a/src/login_sql/char_int.h
+++ /dev/null
@@ -1,2 +0,0 @@
-int char_anti_freeze_system(int, unsigned int, int, int);
-int parse_fromchar(int);
diff --git a/src/login_sql/login.c b/src/login_sql/login.c
index 3785d33d8..ff9e4706a 100644
--- a/src/login_sql/login.c
+++ b/src/login_sql/login.c
@@ -4,18 +4,56 @@
#include <sys/types.h>
+#ifdef LCCWIN32
+#include <winsock.h>
+#pragma lib <libmysql.lib>
+#else
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winsock2.h>
+#include <time.h>
+void Gettimeofday(struct timeval *timenow)
+{
+ time_t t;
+ t = clock();
+ timenow->tv_usec = t;
+ timenow->tv_sec = t / CLK_TCK;
+ return;
+}
+#define gettimeofday(timenow, dummy) Gettimeofday(timenow)
+#pragma comment(lib,"libmysql.lib")
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+#endif
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
+#include <sys/stat.h> // for stat/lstat/fstat
#include <signal.h>
#include <fcntl.h>
#include <string.h>
-#include "timer.h"
-
+//add include for DBMS(mysql)
+#include <mysql.h>
+
+#include "../common/core.h"
+#include "../common/socket.h"
+#include "../common/malloc.h"
+#include "../common/db.h"
+#include "../common/timer.h"
+#include "../common/strlib.h"
+#include "../common/mmo.h"
+#include "../common/version.h"
#include "login.h"
-#include "login_int.h"
-#include "char_int.h"
#ifdef PASSWORDENC
#include "md5calc.h"
@@ -26,66 +64,42 @@
#endif
#define J_MAX_MALLOC_SIZE 65535
-// Login Listening Port
-int login_port = 6900;
-
-struct auth_fifo auth_fifo[AUTH_FIFO_SIZE];
-
-int auth_fifo_pos;
-
-// MySQL Query
-char tmpsql[65535], prev_query[65535];
-
-// MySQL Connection Handle
-MYSQL mysql_handle;
-MYSQL_RES* sql_res ;
-MYSQL_ROW sql_row ;
-
-// It's to check IP of a player between login-server and char-server (part of anti-hacking system)
-int check_ip_flag;
-
-// Login's FD
-int login_fd;
-// LAN IP of char-server and subnet mask(Kashy)
-char lan_char_ip[16];
-int subnetmaski[4];
+//-----------------------------------------------------
+// global variable
+//-----------------------------------------------------
+int account_id_count = START_ACCOUNT_NUM;
+int server_num;
+int new_account_flag = 0; //Set from config too XD [Sirius]
+char bind_ip_str[16];
+in_addr_t bind_ip;
+int login_port = 6900;
+char lan_char_ip[128]; // Lan char ip added by kashy
+int subnetmaski[4]; // Subnetmask added by kashy
-// Char-server data
struct mmo_char_server server[MAX_SERVERS];
int server_fd[MAX_SERVERS];
-unsigned char servers_connected = 0;
-
-// Anti-freeze Data
-int server_freezeflag[MAX_SERVERS];
-int anti_freeze_enable = 0;
-int ANTI_FREEZE_INTERVAL = 15;
-
-// MD5 Key Data for encrypted login
-char md5key[20];
-int md5keylen = 16;
-// Auth FIFO Position
-int auth_fifo_pos = 0;
+int login_fd;
//Added for Mugendai's I'm Alive mod
int imalive_on=0;
int imalive_time=60;
-
//Added by Mugendai for GUI
int flush_on=1;
int flush_time=100;
-// Date format for bans
char date_format[32] = "%Y-%m-%d %H:%M:%S";
+int auth_num = 0, auth_max = 0;
-// minimum level of player/GM (0: player, 1-99: gm) to connect on the server
-int min_level_to_connect = 0;
+int min_level_to_connect = 0; // minimum level of player/GM (0: player, 1-99: gm) to connect on the server
+int check_ip_flag = 1; // It's to check IP of a player between login-server and char-server (part of anti-hacking system)
+int check_client_version = 0; //Client version check ON/OFF .. (sirius)
+int client_version_to_connect = 20; //Client version needed to connect ..(sirius)
+int register_users_online = 1;
-// It's to check IP of a player between login-server and char-server (part of anti-hacking system)
-int check_ip_flag = 1;
+MYSQL mysql_handle;
-// Dynamic IP Ban config
int ipban = 1;
int dynamic_account_ban = 1;
int dynamic_account_ban_class = 0;
@@ -94,160 +108,116 @@ int dynamic_pass_failure_ban_time = 5;
int dynamic_pass_failure_ban_how_many = 3;
int dynamic_pass_failure_ban_how_long = 60;
-// MySQL Config
int login_server_port = 3306;
-char login_server_ip[16] = "127.0.0.1";
-char login_server_id[16] = "ragnarok";
-char login_server_pw[16] = "ragnarok";
-char login_server_db[16] = "ragnarok";
+char login_server_ip[32] = "127.0.0.1";
+char login_server_id[32] = "ragnarok";
+char login_server_pw[32] = "ragnarok";
+char login_server_db[32] = "ragnarok";
int use_md5_passwds = 0;
+char login_db[256] = "login";
+char loginlog_db[256] = "loginlog";
+
+// added to help out custom login tables, without having to recompile
+// source so options are kept in the login_athena.conf or the inter_athena.conf
+char login_db_account_id[256] = "account_id";
+char login_db_userid[256] = "userid";
+char login_db_user_pass[256] = "user_pass";
+char login_db_level[256] = "level";
-// MySQL custom table and column names
-char login_db[32] = "login";
-char loginlog_db[32] = "loginlog";
-char login_db_account_id[32] = "account_id";
-char login_db_userid[32] = "userid";
-char login_db_user_pass[32] = "user_pass";
-char login_db_level[32] = "level";
+char tmpsql[65535], tmp_sql[65535];
-// Console interface on/off
int console = 0;
-// Online User DB
-struct dbt *online_db;
+int case_sensitive = 1;
+
+//-----------------------------------------------------
+
+#define AUTH_FIFO_SIZE 256
+struct {
+ int account_id,login_id1,login_id2;
+ int ip,sex,delflag;
+} auth_fifo[AUTH_FIFO_SIZE];
+
+int auth_fifo_pos = 0;
-// GM Database
-struct dbt *gm_db;
-int lowest_gm_level = 1;
+
+//-----------------------------------------------------
+
+static char md5key[20], md5keylen = 16;
+
+struct dbt *online_db;
//-----------------------------------------------------
// Online User Database [Wizputer]
//-----------------------------------------------------
void add_online_user(int account_id) {
- int *p;
- p = malloc(sizeof(int));
- if (p == NULL) {
- printf("add_online_user: memory allocation failure (malloc)!\n");
- exit(0);
- }
- p = &account_id;
- numdb_insert(online_db, account_id, p);
+ int *p;
+ if(register_users_online <= 0)
+ return;
+ p = (int*)aMalloc(sizeof(int));
+ *p = account_id;
+ numdb_insert(online_db, account_id, p);
}
int is_user_online(int account_id) {
- int *p;
-
- p = numdb_search(online_db, account_id);
- if (p == NULL)
+ int *p;
+ if(register_users_online <= 0)
return 0;
- #ifdef DEBUG
- printf("Acccount [%d] Online\n",*p);
- #endif
- return 1;
+ p = (int*)numdb_search(online_db, account_id);
+ if (p != NULL)
+ printf("Acccount %d\n",*p);
+
+ return (p != NULL);
}
void remove_online_user(int account_id) {
- int *p;
- p = numdb_erase(online_db,account_id);
- free(p);
-}
-
-//----------------------------------------------
-//SQL Commands ( Original by Clownisius ) [Edit: Wizputer]
-//----------------------------------------------
-
-void sql_query(char* query,char function[32]) {
- if(mysql_query(&mysql_handle, query)){
- printf("---------- SQL error report ----------\n");
- printf("MySQL Server Error: %s\n", mysql_error(&mysql_handle));
- printf("Query: %s\n", query);
- printf("In function: %s \n", function);
- printf("\nPrevious query: %s\n", prev_query);
-// if (strcmp(mysql_error(&mysql_handle),"CR_COMMANDS_OUT_OF_SYNC") !=0) printf(" - = Shutting down Char Server = - \n\n");
- printf("-------- End SQL Error Report --------\n");
-// printf("Uncontrolled param: %s",&mysql_handle);
-// if (strcmp(mysql_error(&mysql_handle),"CR_COMMANDS_OUT_OF_SYNC") !=0) exit(1);
- }
-
- strcpy(prev_query,query);
-
+ int *p;
+ if(register_users_online <= 0)
+ return;
+ p = (int*)numdb_erase(online_db,account_id);
+ aFree(p);
}
//-----------------------------------------------------
-// check user level [Wizputer]
+// check user level
//-----------------------------------------------------
-unsigned char isGM(int account_id) {
- unsigned char *level;
-
- level = numdb_search(gm_db, account_id);
- if (level == NULL)
- return 0;
-
- return *level;
-}
-
-static int gmdb_final(void *key,void *data,va_list ap) {
- unsigned char *level;
-
- nullpo_retr(0, level=data);
-
- free(level);
-
- return 0;
-}
+int isGM(int account_id) {
+ int level;
-void do_final_gmdb(void) {
- if(gm_db){
- numdb_final(gm_db,gmdb_final);
- gm_db=NULL;
+ MYSQL_RES* sql_res;
+ MYSQL_ROW sql_row;
+ level = 0;
+ sprintf(tmpsql,"SELECT `%s` FROM `%s` WHERE `%s`='%d'", login_db_level, login_db, login_db_account_id, account_id);
+ if (mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error (select GM Level to Memory)- %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle);
+ if (sql_res) {
+ sql_row = mysql_fetch_row(sql_res);
+ level = atoi(sql_row[0]);
+ if (level > 99)
+ level = 99;
}
-}
-
-void read_GMs(int fd) {
- unsigned char *level;
- int i=0;
-
- if(gm_db)
- do_final_gmdb();
-
- gm_db = numdb_init();
-
- sprintf(tmpsql,"SELECT `%s`,`%s` FROM `%s` WHERE `%s` > '%d'", login_db_account_id, login_db_level, login_db,login_db_level,lowest_gm_level);
- sql_query(tmpsql,"read_GMs");
-
- WFIFOW(fd, 0) = 0x2732;
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
- for(i=0;(sql_row = mysql_fetch_row(sql_res));i++) {
- level = malloc(sizeof(unsigned char));
-
- if( (*level = atoi(sql_row[1])) > 99 )
- *level = 99;
-
- numdb_insert(gm_db, atoi(sql_row[0]), level);
-
- WFIFOL(fd,6+5*i) = atoi(sql_row[0]);
- WFIFOB(fd,10+5*i) = *level;
- }
- WFIFOW(fd,2) = i;
- }
+ if (level == 0) {
+ return 0;
+ //not GM
+ }
- WFIFOSET(fd,6+5*i);
+ mysql_free_result(sql_res);
- mysql_free_result(sql_res);
+ return level;
}
-
//---------------------------------------------------
// E-mail check: return 0 (not correct) or 1 (valid).
//---------------------------------------------------
-int e_mail_check(unsigned char *email) {
+int e_mail_check(char *email) {
char ch;
- unsigned char* last_arobas;
+ char* last_arobas;
// athena limits
if (strlen(email) < 3 || strlen(email) > 39)
@@ -282,56 +252,69 @@ int e_mail_check(unsigned char *email) {
}
//-----------------------------------------------------
-// Connect to MySQL
+// Read Account database - mysql db
//-----------------------------------------------------
int mmo_auth_sqldb_init(void) {
- printf("Login-server starting...\n");
+ printf("Login server init....\n");
// memory initialize
- #ifdef DEBUG
printf("memory initialize....\n");
- #endif
mysql_init(&mysql_handle);
// DB connection start
- printf("Connecting to Login Database Server...\n");
+ printf("Connect Login Database Server....\n");
if (!mysql_real_connect(&mysql_handle, login_server_ip, login_server_id, login_server_pw,
login_server_db, login_server_port, (char *)NULL, 0)) {
// pointer check
printf("%s\n", mysql_error(&mysql_handle));
exit(1);
} else {
- printf("Connected to MySQL Server\n");
+ printf("connect success!\n");
}
- //delete all server status
- sprintf(tmpsql,"TRUNCATE TABLE `sstatus`");
- sql_query(tmpsql,"mmo_db_close");
-
sprintf(tmpsql, "INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '', 'lserver', '100','login server started')", loginlog_db);
- sql_query(tmpsql,"mmo_auth_sqldb_init");
+
+ //query
+ if (mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
return 0;
}
//-----------------------------------------------------
-// Close MySQL and Close all sessions
+// DB server connect check
+//-----------------------------------------------------
+void mmo_auth_sqldb_sync(void) {
+ // db connect check? or close?
+ // ping pong DB server -if losted? then connect try. else crash.
+}
+
+//-----------------------------------------------------
+// close DB
//-----------------------------------------------------
void mmo_db_close(void) {
int i, fd;
//set log.
sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '', 'lserver','100', 'login server shutdown')", loginlog_db);
- sql_query(tmpsql,"mmo_db_close");
+
+ //query
+ if (mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
//delete all server status
- sprintf(tmpsql,"TRUNCATE TABLE `sstatus`");
- sql_query(tmpsql,"mmo_db_close");
+ sprintf(tmpsql,"DELETE FROM `sstatus`");
+ //query
+ if (mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
mysql_close(&mysql_handle);
- printf("MySQL Connection closed\n");
+ printf("close DB connect....\n");
for (i = 0; i < MAX_SERVERS; i++) {
if ((fd = server_fd[i]) >= 0)
@@ -341,96 +324,274 @@ void mmo_db_close(void) {
}
//-----------------------------------------------------
-// Auth account
+// Make new account
+//-----------------------------------------------------
+int mmo_auth_sqldb_new(struct mmo_account* account,const char *tmpstr, char sex) {
+ //no need on DB version
+
+ printf("Request new account.... - not support on this version\n");
+
+ return 0;
+}
+
+//-----------------------------------------------------
+// Make new account
+//-----------------------------------------------------
+int mmo_auth_new(struct mmo_account* account, const char *tmpstr, char sex) {
+
+ return 0;
+}
+
+#ifdef LCCWIN32
+extern void gettimeofday(struct timeval *t, struct timezone *dummy);
+#endif
+
+//-----------------------------------------------------
+// Auth
//-----------------------------------------------------
int mmo_auth( struct mmo_account* account , int fd){
struct timeval tv;
+ time_t ban_until_time;
char tmpstr[256];
- char t_uid[32], t_pass[32];
- char user_password[32];
+ char t_uid[256], t_pass[256];
+ char user_password[256];
- char ip[16];
+ //added for account creation _M _F
+ int len;
- int encpasswdok = 0;
- int state;
+ MYSQL_RES* sql_res;
+ MYSQL_ROW sql_row;
+ //int sql_fields, sql_cnt;
+ char md5str[64], md5bin[32];
- #ifdef PASSWORDENC
- char logbuf[1024], *p = logbuf;
- char md5str[64],md5bin[32];
- int j;
- #endif
+ char ip[16];
unsigned char *sin_addr = (unsigned char *)&session[fd]->client_addr.sin_addr;
- sprintf(ip, "%d.%d.%d.%d", sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3]);
- #ifdef DEBUG
- printf ("Starting auth for [%s]...\n",ip);
- #endif
- // auth start : time seed
+ printf ("auth start...\n");
+ sprintf(ip, "%d.%d.%d.%d", sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3]);
+
+ //accountreg with _M/_F .. [Sirius]
+ len = strlen(account->userid) -2;
+
+ if (account->passwdenc == 0 && account->userid[len] == '_' &&
+ (account->userid[len+1] == 'F' || account->userid[len+1] == 'M') && new_account_flag == 1 &&
+ account_id_count <= END_ACCOUNT_NUM && len >= 4 && strlen(account->passwd) >= 4) {
+ if (new_account_flag == 1)
+ account->userid[len] = '\0';
+ sprintf(tmp_sql, "SELECT `%s` FROM `%s` WHERE `userid` = '%s'", login_db_userid, login_db, account->userid);
+ if(mysql_query(&mysql_handle, tmp_sql)){
+ printf("SQL error (_M/_F reg): %s", mysql_error(&mysql_handle));
+ }else{
+ sql_res = mysql_store_result(&mysql_handle);
+ if(mysql_num_rows(sql_res) == 0){
+ //ok no existing acc,
+ printf("Adding a new account user: %s with passwd: %s sex: %c (ip: %s)\n", account->userid, account->passwd, account->userid[len+1], ip);
+ sprintf(tmp_sql, "INSERT INTO `%s` (`%s`, `%s`, `sex`, `email`) VALUES ('%s', '%s', '%c', '%s')", login_db, login_db_userid, login_db_user_pass, account->userid, account->passwd, account->userid[len+1], "a@a.com");
+ if(mysql_query(&mysql_handle, tmp_sql)){
+ //Failed to insert new acc :/
+ printf("SQL Error (_M/_F reg) .. insert ..: %s", mysql_error(&mysql_handle));
+ }//sql query check to insert
+ }//rownum check (0!)
+ mysql_free_result(sql_res);
+ }//sqlquery
+ }//all values for NEWaccount ok ?
+
+
+
+ // auth start : time seed
gettimeofday(&tv, NULL);
- strftime(tmpstr, 24, "%Y-%m-%d %H:%M:%S",localtime(&(tv.tv_sec)));
+ strftime(tmpstr, 24, "%Y-%m-%d %H:%M:%S",localtime((const time_t*)&(tv.tv_sec)));
sprintf(tmpstr+19, ".%03d", (int)tv.tv_usec/1000);
jstrescapecpy(t_uid,account->userid);
jstrescapecpy(t_pass, account->passwd);
+
// make query
sprintf(tmpsql, "SELECT `%s`,`%s`,`%s`,`lastlogin`,`logincount`,`sex`,`connect_until`,`last_ip`,`ban_until`,`state`,`%s`"
- " FROM `%s` WHERE `%s`='%s'", login_db_account_id, login_db_userid, login_db_user_pass, login_db_level, login_db, login_db_userid, t_uid);
+ " FROM `%s` WHERE %s `%s`='%s'", login_db_account_id, login_db_userid, login_db_user_pass, login_db_level, login_db, case_sensitive ? "BINARY" : "", login_db_userid, t_uid);
//login {0-account_id/1-userid/2-user_pass/3-lastlogin/4-logincount/5-sex/6-connect_untl/7-last_ip/8-ban_until/9-state}
- sql_query(tmpsql,"mmo_auth");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
- if(!(sql_row = mysql_fetch_row(sql_res))) {
- #ifdef DEBUG
- printf ("Auth failed: No Account Time: [%s] Username: [%s] Password: [%s]\n", tmpstr, account->userid, account->passwd);
- #endif
+ // query
+ if (mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle) ;
+ if (sql_res) {
+ sql_row = mysql_fetch_row(sql_res); //row fetching
+ if (!sql_row) {
+ //there's no id.
+ printf ("auth failed no account %s %s %s\n", tmpstr, account->userid, account->passwd);
mysql_free_result(sql_res);
return 0;
}
} else {
- #ifdef DEBUG
- printf("mmo_auth DB result error\n");
- #endif
+ printf("mmo_auth DB result error ! \n");
return 0;
}
+
+ //Client Version check[Sirius]
+ if(check_client_version == 1 && account->version != 0){
+ if(account->version != client_version_to_connect){
+ mysql_free_result(sql_res);
+ return 6;
+ }
+ }
+
+ // Documented by CLOWNISIUS || LLRO || Gunstar lead this one with me
+ // IF changed to diferent returns~ you get diferent responses from your msgstringtable.txt
+ //Ireturn 2 == line 9
+ //Ireturn 5 == line 311
+ //Ireturn 6 == line 450
+ //Ireturn 7 == line 440
+ //Ireturn 8 == line 682
+ //Ireturn 9 == line 704
+ //Ireturn 10 == line 705
+ //Ireturn 11 == line 706
+ //Ireturn 12 == line 707
+ //Ireturn 13 == line 708
+ //Ireturn 14 == line 709
+ //Ireturn 15 == line 710
+ //Ireturn -1 == line 010
+ // Check status
+ {
+ int encpasswdok = 0;
- account->ban_until_time = atol(sql_row[8]);
- state = atoi(sql_row[9]);
+ if (atoi(sql_row[9]) == -3) {
+ //id is banned
+ mysql_free_result(sql_res);
+ return -3;
+ } else if (atoi(sql_row[9]) == -2) { //dynamic ban
+ //id is banned
+ mysql_free_result(sql_res);
+ //add IP list.
+ return -2;
+ }
- if (state) {
- switch(state) { // packet 0x006a value + 1
+ if (use_md5_passwds) {
+ MD5_String(account->passwd,user_password);
+ } else {
+ jstrescapecpy(user_password, account->passwd);
+ }
+ printf("account id ok encval:%d\n",account->passwdenc);
+#ifdef PASSWORDENC
+ if (account->passwdenc > 0) {
+ int j = account->passwdenc;
+ printf ("start md5calc..\n");
+ if (j > 2)
+ j = 1;
+ do {
+ if (j == 1) {
+ sprintf(md5str, "%s%s", md5key,sql_row[2]);
+ } else if (j == 2) {
+ sprintf(md5str, "%s%s", sql_row[2], md5key);
+ } else
+ md5str[0] = 0;
+ printf("j:%d mdstr:%s\n", j, md5str);
+ MD5_String2binary(md5str, md5bin);
+ encpasswdok = (memcmp(user_password, md5bin, 16) == 0);
+ } while (j < 2 && !encpasswdok && (j++) != account->passwdenc);
+ //printf("key[%s] md5 [%s] ", md5key, md5);
+ printf("client [%s] accountpass [%s]\n", user_password, sql_row[2]);
+ printf ("end md5calc..\n");
+ }
+#endif
+ if ((strcmp(user_password, sql_row[2]) && !encpasswdok)) {
+ if (account->passwdenc == 0) {
+ printf ("auth failed pass error %s %s %s" RETCODE, tmpstr, account->userid, user_password);
+#ifdef PASSWORDENC
+ } else {
+ char logbuf[1024], *p = logbuf;
+ int j;
+ p += sprintf(p, "auth failed pass error %s %s recv-md5[", tmpstr, account->userid);
+ for(j = 0; j < 16; j++)
+ p += sprintf(p, "%02x", ((unsigned char *)user_password)[j]);
+ p += sprintf(p, "] calc-md5[");
+ for(j = 0; j < 16; j++)
+ p += sprintf(p, "%02x", ((unsigned char *)md5bin)[j]);
+ p += sprintf(p, "] md5key[");
+ for(j = 0; j < md5keylen; j++)
+ p += sprintf(p, "%02x", ((unsigned char *)md5key)[j]);
+ p += sprintf(p, "]" RETCODE);
+ printf("%s\n", p);
+#endif
+ }
+ return 1;
+ }
+ printf("auth ok %s %s" RETCODE, tmpstr, account->userid);
+ }
+
+/*
+// do not remove this section. this is meant for future, and current forums usage
+// as a login manager and CP for login server. [CLOWNISIUS]
+ if (atoi(sql_row[10]) == 1) {
+ return 4;
+ }
+
+ if (atoi(sql_row[10]) >= 5) {
+ switch(atoi(sql_row[10])) {
+ case 5:
+ return 5;
+ break;
+ case 6:
+ return 7;
+ break;
+ case 7:
+ return 9;
+ break;
+ case 8:
+ return 10;
+ break;
+ case 9:
+ return 11;
+ break;
+ default:
+ return 10;
+ break;
+ }
+ }
+*/
+ ban_until_time = atol(sql_row[8]);
+
+ //login {0-account_id/1-userid/2-user_pass/3-lastlogin/4-logincount/5-sex/6-connect_untl/7-last_ip/8-ban_until/9-state}
+ if (ban_until_time != 0) { // if account is banned
+ strftime(tmpstr, 20, date_format, localtime(&ban_until_time));
+ tmpstr[19] = '\0';
+ if (ban_until_time > time(NULL)) { // always banned
+ return 6; // 6 = Your are Prohibited to log in until %s
+ } else { // ban is finished
+ // reset the ban time
+ if (atoi(sql_row[9])==7) {//it was a temp ban - so we set STATE to 0
+ sprintf(tmpsql, "UPDATE `%s` SET `ban_until`='0', `state`='0' WHERE %s `%s`='%s'", login_db, case_sensitive ? "BINARY" : "", login_db_userid, t_uid);
+ strcpy(sql_row[9],"0"); //we clear STATE
+ } else //it was a permanent ban + temp ban. So we leave STATE = 5, but clear the temp ban
+ sprintf(tmpsql, "UPDATE `%s` SET `ban_until`='0' WHERE %s `%s`='%s'", login_db, case_sensitive ? "BINARY" : "", login_db_userid, t_uid);
+
+ if (mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ }
+ }
+
+ if (atoi(sql_row[9])) {
+ switch(atoi(sql_row[9])) { // packet 0x006a value + 1
case 1: // 0 = Unregistered ID
case 2: // 1 = Incorrect Password
case 3: // 2 = This ID is expired
case 4: // 3 = Rejected from Server
case 5: // 4 = You have been blocked by the GM Team
case 6: // 5 = Your Game's EXE file is not the latest version
+ case 7: // 6 = Your are Prohibited to log in until %s
case 8: // 7 = Server is jammed due to over populated
case 9: // 8 = No MSG (actually, all states after 9 except 99 are No MSG, use only this)
case 100: // 99 = This ID has been totally erased
- #ifdef DEBUG
- printf("Auth Error #%d\n", state);
- #endif
- mysql_free_result(sql_res);
- return state;
+ printf("Auth Error #%d\n", atoi(sql_row[9]));
+ return atoi(sql_row[9]) - 1;
break;
- case 7: // 6 = Your are Prohibited to log in until %s
- strftime(tmpstr, 20, date_format, localtime(&account->ban_until_time));
- tmpstr[19] = '\0';
- if (account->ban_until_time > time(NULL)) { // always banned
- mysql_free_result(sql_res);
- return 7;
- } else { // ban is finished
- // reset the ban time
- sprintf(tmpsql, "UPDATE `%s` SET `ban_until`='0',`state`='0' WHERE BINARY `%s`='%s'", login_db, login_db_userid, t_uid);
- sql_query(tmpsql,"mmo_auth");
- }
- break;
default:
- return 100; // 99 = ID has been totally erased
+ return 99; // 99 = ID has been totally erased
break;
}
}
@@ -439,117 +600,492 @@ int mmo_auth( struct mmo_account* account , int fd){
return 2; // 2 = This ID is expired
}
- if ( is_user_online(atol(sql_row[0])) ) {
- printf("User [%s] is already online - Rejected.\n",sql_row[1]);
- return 3; // Rejected
- }
+ if ( is_user_online(atol(sql_row[0])) && register_users_online > 0) {
+ printf("User [%s] is already online - Rejected.\n",sql_row[1]);
+#ifndef TWILIGHT
+ return 3; // Rejected
+#endif
+ }
- if (use_md5_passwds) {
- MD5_String(account->passwd,user_password);
- } else {
- jstrescapecpy(user_password, account->passwd);
+ account->account_id = atoi(sql_row[0]);
+ account->login_id1 = rand();
+ account->login_id2 = rand();
+ memcpy(tmpstr, sql_row[3], 19);
+ memcpy(account->lastlogin, tmpstr, 24);
+ account->sex = sql_row[5][0] == 'S' ? 2 : sql_row[5][0]=='M';
+
+ sprintf(tmpsql, "UPDATE `%s` SET `lastlogin` = NOW(), `logincount`=`logincount` +1, `last_ip`='%s' WHERE %s `%s` = '%s'",
+ login_db, ip, case_sensitive ? "BINARY" : "", login_db_userid, sql_row[1]);
+ mysql_free_result(sql_res) ; //resource free
+ if (mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
}
- #ifdef DEBUG
- printf("Account [ok] Pass Encode Value: [%d]\n",account->passwdenc);
- #endif
+ return -1;
+}
-#ifdef PASSWORDENC
- if (account->passwdenc > 0) {
- j = account->passwdenc;
+// Send to char
+int charif_sendallwos(int sfd, unsigned char *buf, unsigned int len) {
+ int i, c;
+ int fd;
+
+ c = 0;
+ for(i = 0; i < MAX_SERVERS; i++) {
+ if ((fd = server_fd[i]) > 0 && fd != sfd) {
+ memcpy(WFIFOP(fd,0), buf, len);
+ WFIFOSET(fd,len);
+ c++;
+ }
+ }
+ return c;
+}
- #ifdef DEBUG
- printf ("Starting md5calc..\n");
- #endif
+//-----------------------------------------------------
+// char-server packet parse
+//-----------------------------------------------------
+int parse_fromchar(int fd){
+ int i, id;
+ MYSQL_RES* sql_res;
+ MYSQL_ROW sql_row = NULL;
- if (j > 2)
- j = 1;
+ unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
+ char ip[16];
- do {
- if (j == 1) {
- sprintf(md5str, "%s%s", md5key,sql_row[2]);
- } else if (j == 2) {
- sprintf(md5str, "%s%s", sql_row[2], md5key);
- } else
- md5str[0] = 0;
- #ifdef DEBUG
- printf("j: [%d] mdstr: [%s]\n", j, md5str);
- #endif
+ sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
- MD5_String2binary(md5str, md5bin);
- encpasswdok = (memcmp(user_password, md5bin, 16) == 0);
- } while (j < 2 && !encpasswdok && (j++) != account->passwdenc);
+ for(id = 0; id < MAX_SERVERS; id++)
+ if (server_fd[id] == fd)
+ break;
- #ifdef DEBUG
- printf("key [%s] md5 [%s] ", md5key, md5str);
- printf("client [%s] accountpass [%s]\n", user_password, sql_row[2]);
- printf ("end md5calc..\n");
- #endif
+ if (id == MAX_SERVERS)
+ session[fd]->eof = 1;
+ if(session[fd]->eof) {
+ if (id < MAX_SERVERS) {
+ printf("Char-server '%s' has disconnected.\n", server[id].name);
+ server_fd[id] = -1;
+ memset(&server[id], 0, sizeof(struct mmo_char_server));
+ // server delete
+ sprintf(tmpsql, "DELETE FROM `sstatus` WHERE `index`='%d'", id);
+ // query
+ if (mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ }
+ close(fd);
+ delete_session(fd);
+ return 0;
}
+
+ while(RFIFOREST(fd) >= 2) {
+// printf("char_parse: %d %d packet case=%x\n", fd, RFIFOREST(fd), RFIFOW(fd, 0));
+
+ switch (RFIFOW(fd,0)) {
+ case 0x2712:
+ if (RFIFOREST(fd) < 19)
+ return 0;
+ {
+ int account_id;
+ account_id = RFIFOL(fd,2); // speed up
+ for(i=0;i<AUTH_FIFO_SIZE;i++){
+ if (auth_fifo[i].account_id == account_id &&
+ auth_fifo[i].login_id1 == RFIFOL(fd,6) &&
+#if CMP_AUTHFIFO_LOGIN2 != 0
+ auth_fifo[i].login_id2 == RFIFOL(fd,10) && // relate to the versions higher than 18
#endif
- if ((strcmp(user_password, sql_row[2]) && !encpasswdok)) {
- if (account->passwdenc == 0) {
- #ifdef DEBUG
- printf ("auth failed pass error %s %s %s" RETCODE, tmpstr, account->userid, user_password);
- #endif
-#ifdef PASSWORDENC
- } else {
- p += sprintf(p, "auth failed pass error %s %s recv-md5[", tmpstr, account->userid);
+ auth_fifo[i].sex == RFIFOB(fd,14) &&
+#if CMP_AUTHFIFO_IP != 0
+ auth_fifo[i].ip == RFIFOL(fd,15) &&
+#endif
+ !auth_fifo[i].delflag) {
+ auth_fifo[i].delflag = 1;
+ printf("auth -> %d\n", i);
+ break;
+ }
+ }
- for(j = 0; j < 16; j++)
- p += sprintf(p, "%02x", ((unsigned char *)user_password)[j]);
+ if (i != AUTH_FIFO_SIZE) { // send account_reg
+ int p;
+ time_t connect_until_time = 0;
+ char email[40] = "";
+ account_id=RFIFOL(fd,2);
+ sprintf(tmpsql, "SELECT `email`,`connect_until` FROM `%s` WHERE `%s`='%d'", login_db, login_db_account_id, account_id);
+ if (mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle) ;
+ if (sql_res) {
+ sql_row = mysql_fetch_row(sql_res);
+ connect_until_time = atol(sql_row[1]);
+ strcpy(email, sql_row[0]);
+ }
+ mysql_free_result(sql_res);
+ if (account_id > 0) {
+ sprintf(tmpsql, "SELECT `str`,`value` FROM `global_reg_value` WHERE `type`='1' AND `account_id`='%d'",account_id);
+ if (mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle) ;
+ if (sql_res) {
+ WFIFOW(fd,0) = 0x2729;
+ WFIFOL(fd,4) = account_id;
+ for(p = 8; (sql_row = mysql_fetch_row(sql_res));p+=36){
+ memcpy(WFIFOP(fd,p), sql_row[0], 32);
+ WFIFOL(fd,p+32) = atoi(sql_row[1]);
+ }
+ WFIFOW(fd,2) = p;
+ WFIFOSET(fd,p);
+ //printf("account_reg2 send : login->char (auth fifo)\n");
+ WFIFOW(fd,0) = 0x2713;
+ WFIFOL(fd,2) = account_id;
+ WFIFOB(fd,6) = 0;
+ memcpy(WFIFOP(fd, 7), email, 40);
+ WFIFOL(fd,47) = (unsigned long) connect_until_time;
+ WFIFOSET(fd,51);
+ }
+ mysql_free_result(sql_res);
+ }
+ } else {
+ WFIFOW(fd,0) = 0x2713;
+ WFIFOL(fd,2) = account_id;
+ WFIFOB(fd,6) = 1;
+ WFIFOSET(fd,51);
+ }
+ }
+ RFIFOSKIP(fd,19);
+ break;
- p += sprintf(p, "] calc-md5[");
+ case 0x2714:
+ if (RFIFOREST(fd) < 6)
+ return 0;
+ // how many users on world? (update)
+ if (server[id].users != RFIFOL(fd,2))
+ {
+ printf("set users %s : %d\n", server[id].name, RFIFOL(fd,2));
+
+ server[id].users = RFIFOL(fd,2);
+ sprintf(tmpsql,"UPDATE `sstatus` SET `user` = '%d' WHERE `index` = '%d'", server[id].users, id);
+ // query
+ if (mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ }
- for(j = 0; j < 16; j++)
- p += sprintf(p, "%02x", ((unsigned char *)md5bin)[j]);
+ // send some answer
+ WFIFOW(fd,0) = 0x2718;
+ WFIFOSET(fd,2);
- p += sprintf(p, "] md5key[");
+ RFIFOSKIP(fd,6);
+ break;
- for(j = 0; j < md5keylen; j++)
- p += sprintf(p, "%02x", ((unsigned char *)md5key)[j]);
+ // We receive an e-mail/limited time request, because a player comes back from a map-server to the char-server
+ case 0x2716:
+ if (RFIFOREST(fd) < 6)
+ return 0;
+ {
+ int account_id;
+ time_t connect_until_time = 0;
+ char email[40] = "";
+ account_id=RFIFOL(fd,2);
+ sprintf(tmpsql,"SELECT `email`,`connect_until` FROM `%s` WHERE `%s`='%d'",login_db, login_db_account_id, account_id);
+ if(mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle) ;
+ if (sql_res) {
+ sql_row = mysql_fetch_row(sql_res);
+ connect_until_time = atol(sql_row[1]);
+ strcpy(email, sql_row[0]);
+ }
+ mysql_free_result(sql_res);
+ //printf("parse_fromchar: E-mail/limited time request from '%s' server (concerned account: %d)\n", server[id].name, RFIFOL(fd,2));
+ WFIFOW(fd,0) = 0x2717;
+ WFIFOL(fd,2) = RFIFOL(fd,2);
+ memcpy(WFIFOP(fd, 6), email, 40);
+ WFIFOL(fd,46) = (unsigned long) connect_until_time;
+ WFIFOSET(fd,50);
+ }
+ RFIFOSKIP(fd,6);
+ break;
- p += sprintf(p, "]" RETCODE);
+ case 0x2720: // GM
+ if (RFIFOREST(fd) < 4)
+ return 0;
+ if (RFIFOREST(fd) < RFIFOW(fd,2))
+ return 0;
+ //oldacc = RFIFOL(fd,4);
+ printf("change GM isn't support in this login server version.\n");
+ printf("change GM error 0 %s\n", RFIFOP(fd, 8));
+
+ RFIFOSKIP(fd, RFIFOW(fd, 2));
+ WFIFOW(fd, 0) = 0x2721;
+ WFIFOL(fd, 2) = RFIFOL(fd,4); // oldacc;
+ WFIFOL(fd, 6) = 0; // newacc;
+ WFIFOSET(fd, 10);
+ return 0;
- #ifdef DEBUG
- printf("%s\n", p);
- #endif
-#endif
- }
- return 2;
- }
+ // Map server send information to change an email of an account via char-server
+ case 0x2722: // 0x2722 <account_id>.L <actual_e-mail>.40B <new_e-mail>.40B
+ if (RFIFOREST(fd) < 86)
+ return 0;
+ {
+ int acc;
+ char actual_email[40], new_email[40];
+ acc = RFIFOL(fd,2);
+ memcpy(actual_email, RFIFOP(fd,6), 40);
+ memcpy(new_email, RFIFOP(fd,46), 40);
+ if (e_mail_check(actual_email) == 0)
+ printf("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual email is invalid (account: %d, ip: %s)" RETCODE,
+ server[id].name, acc, ip);
+ else if (e_mail_check(new_email) == 0)
+ printf("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a invalid new e-mail (account: %d, ip: %s)" RETCODE,
+ server[id].name, acc, ip);
+ else if (strcmpi(new_email, "a@a.com") == 0)
+ printf("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a default e-mail (account: %d, ip: %s)" RETCODE,
+ server[id].name, acc, ip);
+ else {
+ sprintf(tmpsql, "SELECT `%s`,`email` FROM `%s` WHERE `%s` = '%d'", login_db_userid, login_db, login_db_account_id, acc);
+ if (mysql_query(&mysql_handle, tmpsql))
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ sql_res = mysql_store_result(&mysql_handle);
+ if (sql_res) {
+ sql_row = mysql_fetch_row(sql_res); //row fetching
+
+ if (strcmpi(sql_row[1], actual_email) == 0) {
+ sprintf(tmpsql, "UPDATE `%s` SET `email` = '%s' WHERE `%s` = '%d'", login_db, new_email, login_db_account_id, acc);
+ // query
+ if (mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ printf("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s)." RETCODE,
+ server[id].name, acc, sql_row[0], actual_email, ip);
+ }
+ }
- #ifdef DEBUG
- printf("Auth ok: Time: [%s] Username: [%s]\n" RETCODE, tmpstr, account->userid);
- #endif
+ }
+ }
+ RFIFOSKIP(fd, 86);
+ break;
- account->account_id = atoi(sql_row[0]);
- account->login_id1 = rand();
- account->login_id2 = rand();
- memcpy(tmpstr, sql_row[3], 19);
- memcpy(account->lastlogin, tmpstr, 24);
- account->sex = sql_row[5][0] == 'S' ? 2 : sql_row[5][0]=='M';
+ case 0x2724: // Receiving of map-server via char-server a status change resquest (by Yor)
+ if (RFIFOREST(fd) < 10)
+ return 0;
+ {
+ int acc, statut;
+ acc = RFIFOL(fd,2);
+ statut = RFIFOL(fd,6);
+ sprintf(tmpsql, "SELECT `state` FROM `%s` WHERE `%s` = '%d'", login_db, login_db_account_id, acc);
+ if (mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle);
+ if (sql_res) {
+ sql_row = mysql_fetch_row(sql_res); // row fetching
+ }
+ if (atoi(sql_row[0]) != statut && statut != 0) {
+ unsigned char buf[16];
+ WBUFW(buf,0) = 0x2731;
+ WBUFL(buf,2) = acc;
+ WBUFB(buf,6) = 0; // 0: change of statut, 1: ban
+ WBUFL(buf,7) = statut; // status or final date of a banishment
+ charif_sendallwos(-1, buf, 11);
+ }
+ sprintf(tmpsql,"UPDATE `%s` SET `state` = '%d' WHERE `%s` = '%d'", login_db, statut,login_db_account_id,acc);
+ //query
+ if(mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ RFIFOSKIP(fd,10);
+ }
+ return 0;
- sprintf(tmpsql, "UPDATE `%s` SET `lastlogin` = NOW(), `logincount`=`logincount` +1, `last_ip`='%s' WHERE BINARY `%s` = '%s'",
- login_db, ip, login_db_userid, sql_row[1]);
- sql_query(tmpsql,"mmo_auth");
+ case 0x2725: // Receiving of map-server via char-server a ban resquest (by Yor)
+ if (RFIFOREST(fd) < 18)
+ return 0;
+ {
+ int acc;
+ struct tm *tmtime;
+ time_t timestamp, tmptime;
+ acc = RFIFOL(fd,2);
+ sprintf(tmpsql, "SELECT `ban_until` FROM `%s` WHERE `%s` = '%d'",login_db,login_db_account_id,acc);
+ if (mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle);
+ if (sql_res) {
+ sql_row = mysql_fetch_row(sql_res); // row fetching
+ }
+ tmptime = atol(sql_row[0]);
+ if (tmptime == 0 || tmptime < time(NULL))
+ timestamp = time(NULL);
+ else
+ timestamp = tmptime;
+ tmtime = localtime(&timestamp);
+ tmtime->tm_year = tmtime->tm_year + (short)RFIFOW(fd,6);
+ tmtime->tm_mon = tmtime->tm_mon + (short)RFIFOW(fd,8);
+ tmtime->tm_mday = tmtime->tm_mday + (short)RFIFOW(fd,10);
+ tmtime->tm_hour = tmtime->tm_hour + (short)RFIFOW(fd,12);
+ tmtime->tm_min = tmtime->tm_min + (short)RFIFOW(fd,14);
+ tmtime->tm_sec = tmtime->tm_sec + (short)RFIFOW(fd,16);
+ timestamp = mktime(tmtime);
+ if (timestamp != -1) {
+ if (timestamp <= time(NULL))
+ timestamp = 0;
+ if (tmptime != timestamp) {
+ if (timestamp != 0) {
+ unsigned char buf[16];
+ WBUFW(buf,0) = 0x2731;
+ WBUFL(buf,2) = acc;
+ WBUFB(buf,6) = 1; // 0: change of statut, 1: ban
+ WBUFL(buf,7) = timestamp; // status or final date of a banishment
+ charif_sendallwos(-1, buf, 11);
+ }
+ printf("Account: %d Banned until: %ld\n", acc, timestamp);
+ sprintf(tmpsql, "UPDATE `%s` SET `ban_until` = '%ld', `state`='7' WHERE `%s` = '%d'", login_db, timestamp, login_db_account_id, acc);
+ // query
+ if (mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ }
+ }
+ RFIFOSKIP(fd,18);
+ break;
+ }
+ return 0;
- mysql_free_result(sql_res) ; //resource free
+ case 0x2727:
+ if (RFIFOREST(fd) < 6)
+ return 0;
+ {
+ int acc,sex;
+ unsigned char buf[16];
+ acc=RFIFOL(fd,4);
+ sprintf(tmpsql,"SELECT `sex` FROM `%s` WHERE `%s` = '%d'",login_db,login_db_account_id,acc);
+
+ if(mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ return 0;
+ }
+
+ sql_res = mysql_store_result(&mysql_handle) ;
+
+ if (sql_res) {
+ if (mysql_num_rows(sql_res) == 0) {
+ mysql_free_result(sql_res);
+ return 0;
+ }
+ sql_row = mysql_fetch_row(sql_res); //row fetching
+ }
+
+ if (strcmpi(sql_row[0], "M") == 0)
+ sex = 1;
+ else
+ sex = 0;
+ sprintf(tmpsql,"UPDATE `%s` SET `sex` = '%c' WHERE `%s` = '%d'", login_db, (sex==0?'M':'F'), login_db_account_id, acc);
+ //query
+ if(mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ WBUFW(buf,0) = 0x2723;
+ WBUFL(buf,2) = acc;
+ WBUFB(buf,6) = sex;
+ charif_sendallwos(-1, buf, 7);
+ RFIFOSKIP(fd,6);
+ }
+ return 0;
+
+ case 0x2728: // save account_reg
+ if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
+ return 0;
+ {
+ int acc,p,j;
+ char str[32];
+ char temp_str[32];
+ int value;
+ acc=RFIFOL(fd,4);
+
+ if (acc>0){
+ unsigned char buf[RFIFOW(fd,2)+1];
+ for(p=8,j=0;p<RFIFOW(fd,2) && j<ACCOUNT_REG2_NUM;p+=36,j++){
+ memcpy(str,RFIFOP(fd,p),32);
+ value=RFIFOL(fd,p+32);
+ sprintf(tmpsql,"DELETE FROM `global_reg_value` WHERE `type`='1' AND `account_id`='%d' AND `str`='%s';",acc,jstrescapecpy(temp_str,str));
+ if(mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sprintf(tmpsql,"INSERT INTO `global_reg_value` (`type`, `account_id`, `str`, `value`) VALUES ( 1 , '%d' , '%s' , '%d');", acc, jstrescapecpy(temp_str,str), value);
+ if(mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ }
+
+ // Send to char
+ memcpy(WBUFP(buf,0),RFIFOP(fd,0),RFIFOW(fd,2));
+ WBUFW(buf,0)=0x2729;
+ charif_sendallwos(fd,buf,WBUFW(buf,2));
+ }
+ }
+ RFIFOSKIP(fd,RFIFOW(fd,2));
+ //printf("login: save account_reg (from char)\n");
+ break;
+
+ case 0x272a: // Receiving of map-server via char-server a unban resquest (by Yor)
+ if (RFIFOREST(fd) < 6)
+ return 0;
+ {
+ int acc;
+ acc = RFIFOL(fd,2);
+ sprintf(tmpsql,"SELECT `ban_until` FROM `%s` WHERE `%s` = '%d'",login_db,login_db_account_id,acc);
+ if(mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle) ;
+ if (sql_res) {
+ sql_row = mysql_fetch_row(sql_res); //row fetching
+ }
+ if (atol(sql_row[0]) != 0) {
+ sprintf(tmpsql,"UPDATE `%s` SET `ban_until` = '0', `state`='0' WHERE `%s` = '%d'", login_db,login_db_account_id,acc);
+ //query
+ if(mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ break;
+ }
+ RFIFOSKIP(fd,6);
+ }
+ return 0;
- return -1;
+ case 0x272b: // Set account_id to online [Wizputer]
+ if (RFIFOREST(fd) < 6)
+ return 0;
+ add_online_user(RFIFOL(fd,2));
+ RFIFOSKIP(fd,6);
+ break;
+
+ case 0x272c: // Set account_id to offline [Wizputer]
+ if (RFIFOREST(fd) < 6)
+ return 0;
+ remove_online_user(RFIFOL(fd,2));
+ RFIFOSKIP(fd,6);
+ break;
+
+ default:
+ printf("login: unknown packet %x! (from char).\n", RFIFOW(fd,0));
+ session[fd]->eof = 1;
+ return 0;
+ }
+ }
+
+ return 0;
}
-//-----------------------------------------
-// Lan ip check ( added by Kashy )
-//-----------------------------------------
+//Lan ip check added by Kashy
int lan_ip_check(unsigned char *p) {
int y;
int lancheck = 1;
int lancharip[4];
unsigned int k0, k1, k2, k3;
-
sscanf(lan_char_ip, "%d.%d.%d.%d", &k0, &k1, &k2, &k3);
lancharip[0] = k0; lancharip[1] = k1; lancharip[2] = k2; lancharip[3] = k3;
@@ -558,35 +1094,392 @@ int lan_ip_check(unsigned char *p) {
lancheck = 0;
break; }
- #ifdef DEBUG
printf("LAN check: %s.\n", (lancheck) ? "\033[1;32mLAN\033[0m" : "\033[1;31mWAN\033[0m");
- #endif
-
return lancheck;
}
+//----------------------------------------------------------------------------------------
+// Default packet parsing (normal players or administation/char-server connection requests)
+//----------------------------------------------------------------------------------------
+int parse_login(int fd) {
+ //int len;
-//-----------------------------------------------------
-// BANNED IP CHECK.
-//-----------------------------------------------------
-int ip_ban_check(int tid, unsigned int tick, int id, int data){
+ MYSQL_RES* sql_res ;
+ MYSQL_ROW sql_row = NULL;
- //query
- if(mysql_query(&mysql_handle, "DELETE FROM `ipbanlist` WHERE `rtime` <= NOW()")) {
- printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ char t_uid[100];
+ //int sql_fields, sql_cnt;
+ struct mmo_account account;
+
+ int result, i;
+ unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
+ char ip[16];
+
+ sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+
+ memset(&account, 0, sizeof(account));
+
+ if (ipban > 0) {
+ //ip ban
+ //p[0], p[1], p[2], p[3]
+ //request DB connection
+ //check
+ sprintf(tmpsql, "SELECT count(*) FROM `ipbanlist` WHERE `list` = '%d.*.*.*' OR `list` = '%d.%d.*.*' OR `list` = '%d.%d.%d.*' OR `list` = '%d.%d.%d.%d'",
+ p[0], p[0], p[1], p[0], p[1], p[2], p[0], p[1], p[2], p[3]);
+ if (mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+
+ sql_res = mysql_store_result(&mysql_handle) ;
+ sql_row = mysql_fetch_row(sql_res); //row fetching
+
+ if (atoi(sql_row[0]) >0) {
+ // ip ban ok.
+ printf ("packet from banned ip : %d.%d.%d.%d" RETCODE, p[0], p[1], p[2], p[3]);
+ sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', 'unknown','-3', 'ip banned')", loginlog_db, p[0], p[1], p[2], p[3]);
+
+ // query
+ if(mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ printf ("close session connection...\n");
+
+ // close connection
+ session[fd]->eof = 1;
+
+ } else {
+ printf ("packet from ip (ban check ok) : %d.%d.%d.%d" RETCODE, p[0], p[1], p[2], p[3]);
+ }
+ mysql_free_result(sql_res);
+ }
+
+ if (session[fd]->eof) {
+ for(i = 0; i < MAX_SERVERS; i++)
+ if (server_fd[i] == fd)
+ server_fd[i] = -1;
+ close(fd);
+ delete_session(fd);
+ return 0;
+ }
+
+ while(RFIFOREST(fd)>=2){
+ printf("parse_login : %d %d packet case=%x\n", fd, RFIFOREST(fd), RFIFOW(fd,0));
+
+ switch(RFIFOW(fd,0)){
+ case 0x200: // New alive packet: structure: 0x200 <account.userid>.24B. used to verify if client is always alive.
+ if (RFIFOREST(fd) < 26)
+ return 0;
+ RFIFOSKIP(fd,26);
+ break;
+
+ case 0x204: // New alive packet: structure: 0x204 <encrypted.account.userid>.16B. (new ragexe from 22 june 2004)
+ if (RFIFOREST(fd) < 18)
+ return 0;
+ RFIFOSKIP(fd,18);
+ break;
+
+ case 0x64: // request client login
+ case 0x01dd: // request client login with encrypt
+ if(RFIFOREST(fd)< ((RFIFOW(fd, 0) ==0x64)?55:47))
+ return 0;
+
+ printf("client connection request %s from %d.%d.%d.%d\n", RFIFOP(fd, 6), p[0], p[1], p[2], p[3]);
+ account.version = RFIFOL(fd, 2);
+ account.userid = (char*)RFIFOP(fd, 6);
+ account.passwd = (char*)RFIFOP(fd, 30);
+#ifdef PASSWORDENC
+ account.passwdenc= (RFIFOW(fd,0)==0x64)?0:PASSWORDENC;
+#else
+ account.passwdenc=0;
+#endif
+ result=mmo_auth(&account, fd);
+
+
+ jstrescapecpy(t_uid,(char*)RFIFOP(fd, 6));
+ if(result==-1){
+ int gm_level = isGM(account.account_id);
+
+ if (min_level_to_connect > gm_level) {
+ WFIFOW(fd,0) = 0x81;
+ WFIFOL(fd,2) = 1; // 01 = Server closed
+ WFIFOSET(fd,3);
+ } else {
+
+ if (p[0] != 127) {
+ sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', '%s','100', 'login ok')", loginlog_db, p[0], p[1], p[2], p[3], t_uid);
+ //query
+ if(mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ }
+ if (gm_level)
+ printf("Connection of the GM (level:%d) account '%s' accepted.\n", gm_level, account.userid);
+ else
+ printf("Connection of the account '%s' accepted.\n", account.userid);
+ server_num=0;
+ for(i = 0; i < MAX_SERVERS; i++) {
+ if (server_fd[i] >= 0) {
+ //Lan check added by Kashy
+ if (lan_ip_check(p))
+ WFIFOL(fd,47+server_num*32) = inet_addr(lan_char_ip);
+ else
+ WFIFOL(fd,47+server_num*32) = server[i].ip;
+ WFIFOW(fd,47+server_num*32+4) = server[i].port;
+ memcpy(WFIFOP(fd,47+server_num*32+6), server[i].name, 20);
+ WFIFOW(fd,47+server_num*32+26) = server[i].users;
+ WFIFOW(fd,47+server_num*32+28) = server[i].maintenance;
+ WFIFOW(fd,47+server_num*32+30) = server[i].new_;
+ server_num++;
+ }
+ }
+ // if at least 1 char-server
+ if (server_num > 0) {
+ WFIFOW(fd,0)=0x69;
+ WFIFOW(fd,2)=47+32*server_num;
+ WFIFOL(fd,4)=account.login_id1;
+ WFIFOL(fd,8)=account.account_id;
+ WFIFOL(fd,12)=account.login_id2;
+ WFIFOL(fd,16)=0;
+ memcpy(WFIFOP(fd,20),account.lastlogin,24);
+ WFIFOB(fd,46)=account.sex;
+ WFIFOSET(fd,47+32*server_num);
+ if(auth_fifo_pos>=AUTH_FIFO_SIZE)
+ auth_fifo_pos=0;
+ auth_fifo[auth_fifo_pos].account_id=account.account_id;
+ auth_fifo[auth_fifo_pos].login_id1=account.login_id1;
+ auth_fifo[auth_fifo_pos].login_id2=account.login_id2;
+ auth_fifo[auth_fifo_pos].sex=account.sex;
+ auth_fifo[auth_fifo_pos].delflag=0;
+ auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr.sin_addr.s_addr;
+ auth_fifo_pos++;
+ } else {
+ WFIFOW(fd,0) = 0x81;
+ WFIFOL(fd,2) = 1; // 01 = Server closed
+ WFIFOSET(fd,3);
+ }
+ }
+ } else {
+ char tmp_sql[512];
+ char error[64];
+ sprintf(tmp_sql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', '%s', '%d','login failed : %%s')", loginlog_db, p[0], p[1], p[2], p[3], t_uid, result);
+ switch((result + 1)) {
+ case -2: //-3 = Account Banned
+ sprintf(tmpsql,tmp_sql,"Account banned.");
+ sprintf(error,"Account banned.");
+ break;
+ case -1: //-2 = Dynamic Ban
+ sprintf(tmpsql,tmp_sql,"dynamic ban (ip and account).");
+ sprintf(error,"dynamic ban (ip and account).");
+ break;
+ case 1: // 0 = Unregistered ID
+ sprintf(tmpsql,tmp_sql,"Unregisterd ID.");
+ sprintf(error,"Unregisterd ID.");
+ break;
+ case 2: // 1 = Incorrect Password
+ sprintf(tmpsql,tmp_sql,"Incorrect Password.");
+ sprintf(error,"Incorrect Password.");
+ break;
+ case 3: // 2 = This ID is expired
+ sprintf(tmpsql,tmp_sql,"Account Expired.");
+ sprintf(error,"Account Expired.");
+ break;
+ case 4: // 3 = Rejected from Server
+ sprintf(tmpsql,tmp_sql,"Rejected from server.");
+ sprintf(error,"Rejected from server.");
+ break;
+ case 5: // 4 = You have been blocked by the GM Team
+ sprintf(tmpsql,tmp_sql,"Blocked by GM.");
+ sprintf(error,"Blocked by GM.");
+ break;
+ case 6: // 5 = Your Game's EXE file is not the latest version
+ sprintf(tmpsql,tmp_sql,"Not latest game EXE.");
+ sprintf(error,"Not latest game EXE.");
+ break;
+ case 7: // 6 = Your are Prohibited to log in until %s
+ sprintf(tmpsql,tmp_sql,"Banned.");
+ sprintf(error,"Banned.");
+ break;
+ case 8: // 7 = Server is jammed due to over populated
+ sprintf(tmpsql,tmp_sql,"Server Over-population.");
+ sprintf(error,"Server Over-population.");
+ break;
+ case 9: // 8 = No MSG (actually, all states after 9 except 99 are No MSG, use only this)
+ sprintf(tmpsql,tmp_sql," ");
+ sprintf(error," ");
+ break;
+ case 100: // 99 = This ID has been totally erased
+ sprintf(tmpsql,tmp_sql,"Account gone.");
+ sprintf(error,"Account gone.");
+ break;
+ default:
+ sprintf(tmpsql,tmp_sql,"Uknown Error.");
+ sprintf(error,"Uknown Error.");
+ break;
+ }
+ //query
+ if(mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ if ((result == 1) && (dynamic_pass_failure_ban != 0)){ // failed password
+ sprintf(tmpsql,"SELECT count(*) FROM `%s` WHERE `ip` = '%d.%d.%d.%d' AND `rcode` = '1' AND `time` > NOW() - INTERVAL %d MINUTE",
+ loginlog_db, p[0], p[1], p[2], p[3], dynamic_pass_failure_ban_time); //how many times filed account? in one ip.
+ if(mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ //check query result
+ sql_res = mysql_store_result(&mysql_handle) ;
+ sql_row = mysql_fetch_row(sql_res); //row fetching
+
+ if (atoi(sql_row[0]) >= dynamic_pass_failure_ban_how_many ) {
+ sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() + INTERVAL %d MINUTE ,'Password error ban: %s')", p[0], p[1], p[2], dynamic_pass_failure_ban_how_long, t_uid);
+ if(mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ }
+ mysql_free_result(sql_res);
+ }
+ else if (result == -2){ //dynamic banned - add ip to ban list.
+ sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() + INTERVAL 1 MONTH ,'Dynamic banned user id : %s')", p[0], p[1], p[2], t_uid);
+ if(mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ result = -3;
+ }else if(result == 6){ //not lastet version ..
+ //result = 5;
+ }
+
+ sprintf(tmpsql,"SELECT `ban_until` FROM `%s` WHERE %s `%s` = '%s'",login_db, case_sensitive ? "BINARY" : "",login_db_userid, t_uid);
+ if(mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ sql_res = mysql_store_result(&mysql_handle) ;
+ if (sql_res) {
+ sql_row = mysql_fetch_row(sql_res); //row fetching
+ }
+ //cannot connect login failed
+ memset(WFIFOP(fd,0),'\0',23);
+ WFIFOW(fd,0)=0x6a;
+ WFIFOB(fd,2)=result;
+ if (result == 6) { // 6 = Your are Prohibited to log in until %s
+ if (atol(sql_row[0]) != 0) { // if account is banned, we send ban timestamp
+ char tmpstr[256];
+ time_t ban_until_time;
+ ban_until_time = atol(sql_row[0]);
+ strftime(tmpstr, 20, date_format, localtime(&ban_until_time));
+ tmpstr[19] = '\0';
+ memcpy(WFIFOP(fd,3), tmpstr, 20);
+ } else { // we send error message
+ memcpy(WFIFOP(fd,3), error, 20);
+ }
+ }
+ WFIFOSET(fd,23);
+ }
+ RFIFOSKIP(fd,(RFIFOW(fd,0)==0x64)?55:47);
+ break;
+
+ case 0x01db: // request password key
+ if (session[fd]->session_data) {
+ printf("login: abnormal request of MD5 key (already opened session).\n");
+ session[fd]->eof = 1;
+ return 0;
+ }
+ printf("Request Password key -%s\n",md5key);
+ RFIFOSKIP(fd,2);
+ WFIFOW(fd,0)=0x01dc;
+ WFIFOW(fd,2)=4+md5keylen;
+ memcpy(WFIFOP(fd,4),md5key,md5keylen);
+ WFIFOSET(fd,WFIFOW(fd,2));
+ break;
+
+ case 0x2710: // request Char-server connection
+ if(RFIFOREST(fd)<86)
+ return 0;
+ {
+ unsigned char* server_name;
+ sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', '%s@%s','100', 'charserver - %s@%d.%d.%d.%d:%d')", loginlog_db, p[0], p[1], p[2], p[3], RFIFOP(fd, 2),RFIFOP(fd, 60),RFIFOP(fd, 60), RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58));
+
+ //query
+ if(mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ printf("server connection request %s @ %d.%d.%d.%d:%d (%d.%d.%d.%d)\n",
+ RFIFOP(fd, 60), RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58),
+ p[0], p[1], p[2], p[3]);
+ account.userid = (char*)RFIFOP(fd, 2);
+ account.passwd = (char*)RFIFOP(fd, 26);
+ account.passwdenc = 0;
+ server_name = RFIFOP(fd,60);
+ result = mmo_auth(&account, fd);
+ //printf("Result: %d - Sex: %d - Account ID: %d\n",result,account.sex,(int) account.account_id);
+
+ if(result == -1 && account.sex==2 && account.account_id<MAX_SERVERS && server_fd[account.account_id]==-1){
+ printf("Connection of the char-server '%s' accepted.\n", server_name);
+ memset(&server[account.account_id], 0, sizeof(struct mmo_char_server));
+ server[account.account_id].ip=RFIFOL(fd,54);
+ server[account.account_id].port=RFIFOW(fd,58);
+ memcpy(server[account.account_id].name,RFIFOP(fd,60),20);
+ server[account.account_id].users=0;
+ server[account.account_id].maintenance=RFIFOW(fd,82);
+ server[account.account_id].new_=RFIFOW(fd,84);
+ server_fd[account.account_id]=fd;
+ sprintf(tmpsql,"DELETE FROM `sstatus` WHERE `index`='%ld'", account.account_id);
+ //query
+ if(mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+
+ jstrescapecpy(t_uid,server[account.account_id].name);
+ sprintf(tmpsql,"INSERT INTO `sstatus`(`index`,`name`,`user`) VALUES ( '%ld', '%s', '%d')",
+ account.account_id, server[account.account_id].name,0);
+ //query
+ if(mysql_query(&mysql_handle, tmpsql)) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+ WFIFOW(fd,0)=0x2711;
+ WFIFOB(fd,2)=0;
+ WFIFOSET(fd,3);
+ session[fd]->func_parse=parse_fromchar;
+ realloc_fifo(fd,FIFOSIZE_SERVERLINK,FIFOSIZE_SERVERLINK);
+ } else {
+ WFIFOW(fd, 0) =0x2711;
+ WFIFOB(fd, 2)=3;
+ WFIFOSET(fd, 3);
+ }
+ }
+ RFIFOSKIP(fd, 86);
+ return 0;
+
+ case 0x7530: // request Athena information
+ WFIFOW(fd,0)=0x7531;
+ WFIFOB(fd,2)=ATHENA_MAJOR_VERSION;
+ WFIFOB(fd,3)=ATHENA_MINOR_VERSION;
+ WFIFOB(fd,4)=ATHENA_REVISION;
+ WFIFOB(fd,5)=ATHENA_RELEASE_FLAG;
+ WFIFOB(fd,6)=ATHENA_OFFICIAL_FLAG;
+ WFIFOB(fd,7)=ATHENA_SERVER_LOGIN;
+ WFIFOW(fd,8)=ATHENA_MOD_VERSION;
+ WFIFOSET(fd,10);
+ RFIFOSKIP(fd,2);
+ printf ("Athena version check...\n");
+ break;
+
+ case 0x7532:
+ default:
+ printf ("End of connection (ip: %s)" RETCODE, ip);
+ session[fd]->eof = 1;
+ return 0;
+ }
}
return 0;
}
-//------------------------------------
// Console Command Parser [Wizputer]
-//------------------------------------
int parse_console(char *buf) {
char *type,*command;
- type = (char *)malloc(64);
- command = (char *)malloc(64);
+ type = (char *)aMalloc(64);
+ command = (char *)aMalloc(64);
memset(type,0,64);
memset(command,0,64);
@@ -598,9 +1491,9 @@ int parse_console(char *buf) {
printf("Type of command: %s || Command: %s \n",type,command);
- if(buf) free(buf);
- if(type) free(type);
- if(command) free(command);
+ if(buf) aFree(buf);
+ if(type) aFree(type);
+ if(command) aFree(command);
return 0;
}
@@ -619,9 +1512,7 @@ int config_switch(const char *str) {
}
-//-------------------------------
-// LAN Support Config (Kashy)
-//-------------------------------
+//Lan Support conf reading added by Kashy
int login_lan_config_read(const char *lancfgName){
int i;
char subnetmask[128];
@@ -676,12 +1567,28 @@ int login_lan_config_read(const char *lancfgName){
}
//-----------------------------------------------------
-// Login configuration
+//BANNED IP CHECK.
+//-----------------------------------------------------
+int ip_ban_check(int tid, unsigned int tick, int id, int data){
+
+ //query
+ if(mysql_query(&mysql_handle, "DELETE FROM `ipbanlist` WHERE `rtime` <= NOW()")) {
+ printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ }
+
+ return 0;
+}
+
+//-----------------------------------------------------
+// reading configuration
//-----------------------------------------------------
int login_config_read(const char *cfgName){
int i;
char line[1024], w1[1024], w2[1024];
FILE *fp;
+ struct hostent *h = NULL;
+
+ bind_ip_str[0] = '\0';
fp=fopen(cfgName,"r");
@@ -689,7 +1596,7 @@ int login_config_read(const char *cfgName){
printf("Configuration file (%s) not found.\n", cfgName);
return 1;
}
- printf("Start reading login configuration: %s\n", cfgName);
+ printf ("start reading configuration...\n");
while(fgets(line, sizeof(line)-1, fp)){
if(line[0] == '/' && line[1] == '/')
continue;
@@ -697,8 +1604,15 @@ int login_config_read(const char *cfgName){
i=sscanf(line,"%[^:]: %[^\r\n]",w1,w2);
if(i!=2)
continue;
-
- else if(strcmpi(w1,"login_port")==0){
+ else if (strcmpi(w1, "bind_ip") == 0) {
+ //bind_ip_set_ = 1;
+ h = gethostbyname (w2);
+ if (h != NULL) {
+ printf("Login server binding IP address : %s -> %d.%d.%d.%d\n", w2, (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+ sprintf(bind_ip_str, "%d.%d.%d.%d", (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+ } else
+ memcpy(bind_ip_str,w2,16);
+ } else if(strcmpi(w1,"login_port")==0){
login_port=atoi(w2);
printf ("set login_port : %s\n",w2);
}
@@ -731,15 +1645,7 @@ int login_config_read(const char *cfgName){
else if(strcmpi(w1,"dynamic_pass_failure_ban_how_long")==0){
dynamic_pass_failure_ban_how_long=atoi(w2);
printf ("set dynamic_pass_failure_ban_how_long : %d\n",dynamic_pass_failure_ban_how_long);
- }
- else if(strcmpi(w1,"anti_freeze_enable")==0){
- anti_freeze_enable = config_switch(w2);
- }
- else if (strcmpi(w1, "anti_freeze_interval") == 0) {
- ANTI_FREEZE_INTERVAL = atoi(w2);
- if (ANTI_FREEZE_INTERVAL < 5)
- ANTI_FREEZE_INTERVAL = 5; // minimum 5 seconds
- }
+ }
else if (strcmpi(w1, "import") == 0) {
login_config_read(w2);
} else if(strcmpi(w1,"imalive_on")==0) { //Added by Mugendai for I'm Alive mod
@@ -750,8 +1656,19 @@ int login_config_read(const char *cfgName){
flush_on = atoi(w2); //Added by Mugendai for GUI
} else if(strcmpi(w1,"flush_time")==0) { //Added by Mugendai for GUI
flush_time = atoi(w2); //Added by Mugendai for GUI
- }
- else if(strcmpi(w1,"use_MD5_passwords")==0){
+ } else if(strcmpi(w1, "new_account") == 0){ //Added by Sirius for new account _M/_F
+ new_account_flag = atoi(w2); //Added by Sirius for new account _M/_F
+ } else if(strcmpi(w1, "check_client_version") == 0){ //Added by Sirius for client version check
+ //check_client_version = config_switch(w2); //Added by Sirius for client version check
+ if(strcmpi(w2,"on") == 0 || strcmpi(w2,"yes") == 0 ){
+ check_client_version = 1;
+ }
+ if(strcmpi(w2,"off") == 0 || strcmpi(w2,"no") == 0 ){
+ check_client_version = 0;
+ }
+ } else if(strcmpi(w1, "client_version_to_connect") == 0){ //Added by Sirius for client version check
+ client_version_to_connect = atoi(w2); //Added by SIrius for client version check
+ } else if(strcmpi(w1,"use_MD5_passwords")==0){
if (!strcmpi(w2,"yes")) {
use_md5_passwds=1;
} else if (!strcmpi(w2,"no")){
@@ -785,15 +1702,21 @@ int login_config_read(const char *cfgName){
if(strcmpi(w2,"on") == 0 || strcmpi(w2,"yes") == 0 )
console = 1;
}
+ else if (strcmpi(w1, "case_sensitive") == 0) {
+ if(strcmpi(w2,"on") == 0 || strcmpi(w2,"yes") == 0 )
+ case_sensitive = 1;
+ if(strcmpi(w2,"off") == 0 || strcmpi(w2,"no") == 0 )
+ case_sensitive = 0;
+ }
+ else if(strcmpi(w1, "register_users_online") == 0) {
+ register_users_online = config_switch(w2);
+ }
}
fclose(fp);
- printf ("End reading login configuration...\n");
+ printf ("End reading configuration...\n");
return 0;
}
-//-----------------------------------------------------
-// SQL configuration
-//-----------------------------------------------------
void sql_config_read(const char *cfgName){ /* Kalaspuff, to get login_db */
int i;
char line[1024], w1[1024], w2[1024];
@@ -802,7 +1725,7 @@ void sql_config_read(const char *cfgName){ /* Kalaspuff, to get login_db */
printf("file not found: %s\n",cfgName);
exit(1);
}
- printf("Start reading SQL configuration: %s\n", cfgName);
+ printf("reading configure: %s\n", cfgName);
while(fgets(line, sizeof(line)-1, fp)){
if(line[0] == '/' && line[1] == '/')
continue;
@@ -850,16 +1773,13 @@ void sql_config_read(const char *cfgName){ /* Kalaspuff, to get login_db */
else if (strcmpi(w1, "loginlog_db") == 0) {
strcpy(loginlog_db, w2);
}
- else if(strcmpi(w1,"lowest_gm_level")==0){
- lowest_gm_level = atoi(w2);
- }
//support the import command, just like any other config
else if(strcmpi(w1,"import")==0){
sql_config_read(w2);
}
- }
- fclose(fp);
- printf("reading SQL configuration done.....\n");
+ }
+ fclose(fp);
+ printf("reading configure done.....\n");
}
@@ -882,64 +1802,67 @@ int flush_timer(int tid, unsigned int tick, int id, int data){
return 0;
}
+//--------------------------------------
+// Function called at exit of the server
+//--------------------------------------
+static int online_db_final(void *key,void *data,va_list ap)
+{
+ int *p = (int *) data;
+ if (p) aFree(p);
+ return 0;
+}
+void do_final(void) {
+ //sync account when terminating.
+ //but no need when you using DBMS (mysql)
+ mmo_db_close();
+ numdb_final(online_db, online_db_final);
+ exit_dbn();
+ timer_final();
+}
+
int do_init(int argc,char **argv){
+ //initialize login server
int i;
- //read login configuration
+ SERVER_TYPE = SERVER_LOGIN;
+ //read login configue
login_config_read( (argc>1)?argv[1]:LOGIN_CONF_NAME );
-
- //read SQL configuration
sql_config_read(SQL_CONF_NAME);
-
- //read LAN support configuation
login_lan_config_read((argc > 1) ? argv[1] : LAN_CONF_NAME);
-
//Generate Passworded Key.
- #ifdef DEBUG
- printf ("memset value: [0] var: [md5key] \n");
- #endif
-
+ printf ("memset md5key \n");
memset(md5key, 0, sizeof(md5key));
-
- #ifdef DEBUG
- printf ("memset var: [md5key] complete\n");
- printf ("Set MD5 key length\n");
- #endif
-
+ printf ("memset md5key complete\n");
+ printf ("memset keyleng\n");
md5keylen=rand()%4+12;
for(i=0;i<md5keylen;i++)
md5key[i]=rand()%255+1;
+ printf ("memset keyleng complete\n");
- #ifdef DEBUG
- printf ("Set MD5 key length complete\n");
- printf ("Set Auth FIFO Size\n");
- #endif
-
+ printf ("set FIFO Size\n");
for(i=0;i<AUTH_FIFO_SIZE;i++)
auth_fifo[i].delflag=1;
+ printf ("set FIFO Size complete\n");
- #ifdef DEBUG
- printf ("Set Auth FIFO Size complete\n");
- printf ("Set max number servers\n");
- #endif
-
+ printf ("set max servers\n");
for(i=0;i<MAX_SERVERS;i++)
server_fd[i]=-1;
-
- #ifdef DEBUG
- printf ("Set max number servers complete\n");
- #endif
-
+ printf ("set max servers complete\n");
//server port open & binding
- login_fd=make_listen_port(login_port);
+ if (bind_ip_str[0] != '\0')
+ bind_ip = inet_addr(bind_ip_str);
+ else
+ bind_ip = INADDR_ANY;
- printf ("Initializing SQL DB\n");
- mmo_auth_sqldb_init();
- printf ("SQL DB Initialized\n");
+ //login_fd=make_listen_port(login_port);
+ login_fd=make_listen_bind(bind_ip,login_port);
- // Close connection to SQL DB at termiantion
- set_termfunc(mmo_db_close);
+ //Auth start
+ printf ("Running mmo_auth_sqldb_init()\n");
+ mmo_auth_sqldb_init();
+ printf ("finished mmo_auth_sqldb_init()\n");
+ set_termfunc(do_final);
//set default parser as parse_login function
set_defaultparse(parse_login);
@@ -952,15 +1875,8 @@ int do_init(int argc,char **argv){
if(flush_on)
add_timer_interval(gettick()+10, flush_timer,0,0,flush_time);
- if(anti_freeze_enable > 0) {
- add_timer_func_list(char_anti_freeze_system, "char_anti_freeze_system");
- i = add_timer_interval(gettick()+1000, char_anti_freeze_system, 0, 0, ANTI_FREEZE_INTERVAL * 1000);
- }
-
// ban deleter timer - 1 minute term
- #ifdef DEBUG
- printf("add interval tic (ip_ban_check)...\n");
- #endif
+ printf("add interval tic (ip_ban_check)....\n");
i=add_timer_interval(gettick()+10, ip_ban_check,0,0,60*1000);
if (console) {
@@ -969,10 +1885,12 @@ int do_init(int argc,char **argv){
}
// Online user database init
- free(online_db);
+ aFree(online_db);
online_db = numdb_init();
printf("The login-server is \033[1;32mready\033[0m (Server is listening on the port %d).\n\n", login_port);
return 0;
}
+
+
diff --git a/src/login_sql/login.h b/src/login_sql/login.h
index 075284450..725c02ada 100644
--- a/src/login_sql/login.h
+++ b/src/login_sql/login.h
@@ -15,126 +15,19 @@
#define START_ACCOUNT_NUM 2000000
#define END_ACCOUNT_NUM 100000000
-//add include for DBMS(mysql)
-#include <mysql.h>
-
-#include "../common/socket.h"
-#include "../common/core.h"
-#include "../common/mmo.h"
-#include "../common/version.h"
-#include "../common/db.h"
-#include "../common/timer.h"
-#include "../common/nullpo.h"
-
-#include "strlib.h"
-
-#ifdef LCCWIN32
-#include <winsock.h>
-#pragma lib <libmysql.lib>
-extern void gettimeofday(struct timeval *t, struct timezone *dummy);
-#else
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <winsock2.h>
-#include <time.h>
-void Gettimeofday(struct timeval *timenow)
-{
- time_t t;
- t = clock();
- timenow->tv_usec = t;
- timenow->tv_sec = t / CLK_TCK;
- return;
-}
-#define gettimeofday(timenow, dummy) Gettimeofday(timenow)
-#pragma comment(lib,"libmysql.lib")
-#else
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#endif
-#endif
-
-// Auth Data
-#define AUTH_FIFO_SIZE 256
-extern struct auth_fifo {
- int account_id,login_id1,login_id2;
- int ip,sex,delflag;
-} auth_fifo[AUTH_FIFO_SIZE];
-
-extern int auth_fifo_pos;
-
-// MySQL Query
-extern char tmpsql[65535], prev_query[65535];
-
-// MySQL Connection Handle
-extern MYSQL mysql_handle;
-extern MYSQL_RES* sql_res ;
-extern MYSQL_ROW sql_row ;
-
-// MySQL custom table and column names
-extern char login_db[32];
-extern char loginlog_db[32];
-extern char login_db_account_id[32];
-extern char login_db_userid[32];
-extern char login_db_user_pass[32];
-extern char login_db_level[32];
-
-// MD5 Key Data for encrypted login
-extern int md5keylen;
-extern char md5key[20];
-
-// Dynamic IP Ban config
-extern int ipban;
-extern int dynamic_account_ban;
-extern int dynamic_account_ban_class;
-extern int dynamic_pass_failure_ban;
-extern int dynamic_pass_failure_ban_time;
-extern int dynamic_pass_failure_ban_how_many;
-extern int dynamic_pass_failure_ban_how_long;
-
-// Date format for bans
-extern char date_format[32];
-
-// minimum level of player/GM (0: player, 1-99: gm) to connect on the server
-extern int min_level_to_connect;
-
-// It's to check IP of a player between login-server and char-server (part of anti-hacking system)
-extern int check_ip_flag;
-
-// Login's FD
-extern int login_fd;
-
-// LAN IP of char-server and subnet mask(Kashy)
-extern char lan_char_ip[16];
-extern int subnetmaski[4];
-
-// Char-server data
-extern struct mmo_char_server server[MAX_SERVERS];
-extern int server_fd[MAX_SERVERS];
-extern unsigned char servers_connected;
-
-// Anti-freeze Data
-extern int server_freezeflag[MAX_SERVERS];
-extern int anti_freeze_enable;
-extern int ANTI_FREEZE_INTERVAL;
-
struct mmo_account {
+ int version; //Added by sirius for versioncheck
char* userid;
char* passwd;
int passwdenc;
-
+
+
long account_id;
long login_id1;
long login_id2;
long char_id;
char lastlogin[24];
int sex;
-
- time_t ban_until_time;
};
struct mmo_char_server {
@@ -143,17 +36,8 @@ struct mmo_char_server {
short port;
int users;
int maintenance;
- int new;
+ int new_;
};
-void sql_query(char*,char*);
-int e_mail_check(unsigned char*);
-void add_online_user(int);
-int is_user_online(int);
-void remove_online_user(int);
-int mmo_auth( struct mmo_account*, int);
-unsigned char isGM(int);
-int lan_ip_check(unsigned char *);
-
#endif
diff --git a/src/login_sql/login_int.c b/src/login_sql/login_int.c
deleted file mode 100644
index 4a3220521..000000000
--- a/src/login_sql/login_int.c
+++ /dev/null
@@ -1,376 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include "login.h"
-#include "char_int.h"
-
-//----------------------
-// Client requesting login [Edit: Wizputer]
-//----------------------
-int client_request_login(int fd,int len,unsigned char *p ) {
- if(len < ((RFIFOW(fd, 0) ==0x64)?55:47))
- return -1;
-
- struct mmo_account account;
- char t_uid[32];
- int server_num = 0,result,i;
-
- if( !servers_connected) {
- WFIFOW(fd,0) = 0x81;
- WFIFOL(fd,2) = 1; // 01 = Server closed
- WFIFOSET(fd,3);
- }
-
- #ifdef DEBUG
- printf("client connection request %s from %d.%d.%d.%d\n", RFIFOP(fd, 6), p[0], p[1], p[2], p[3]);
- #endif
-
- account.userid = RFIFOP(fd, 6);
- account.passwd = RFIFOP(fd, 30);
-#ifdef PASSWORDENC
- account.passwdenc= (RFIFOW(fd,0)==0x64)?0:PASSWORDENC;
-#else
- account.passwdenc=0;
-#endif
- result=mmo_auth(&account, fd);
-
- jstrescapecpy(t_uid,RFIFOP(fd, 6));
- if(result==-1){
- unsigned char gm_level = isGM(account.account_id);
- if (min_level_to_connect > gm_level || !servers_connected) {
- WFIFOW(fd,0) = 0x81;
- WFIFOL(fd,2) = 1; // 01 = Server closed
- WFIFOSET(fd,3);
- } else {
- if (p[0] != 127) {
- sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', '%s','100', 'login ok')", loginlog_db, p[0], p[1], p[2], p[3], t_uid);
- sql_query(tmpsql,"client_request_login");
- }
-
- if (gm_level) {
- #ifdef DEBUG
- printf("Connection of the GM (level:%d) account '%s' accepted.\n", gm_level, account.userid);
- #endif
- } else {
- #ifdef DEBUG
- printf("Connection of the account '%s' accepted.\n", account.userid);
- #endif
- }
-
- for(i = 0; i < MAX_SERVERS || server_num < servers_connected ; i++)
- if (server_fd[i] >= 0) {
- //Lan check added by Kashy
- if (lan_ip_check(p))
- WFIFOL(fd,47+server_num*32) = inet_addr(lan_char_ip);
- else
- WFIFOL(fd,47+server_num*32) = server[i].ip;
-
- WFIFOW(fd,47+server_num*32+4) = server[i].port;
- memcpy(WFIFOP(fd,47+server_num*32+6), server[i].name, 20);
- WFIFOW(fd,47+server_num*32+26) = server[i].users;
- WFIFOW(fd,47+server_num*32+28) = server[i].maintenance;
- WFIFOW(fd,47+server_num*32+30) = server[i].new;
- server_num++;
- }
-
- WFIFOW(fd,0)=0x69;
- WFIFOW(fd,2)=47+32*server_num;
- WFIFOL(fd,4)=account.login_id1;
- WFIFOL(fd,8)=account.account_id;
- WFIFOL(fd,12)=account.login_id2;
- WFIFOL(fd,16)=0;
- memcpy(WFIFOP(fd,20),account.lastlogin,24);
- WFIFOB(fd,46)=account.sex;
- WFIFOSET(fd,47+32*server_num);
-
- if(auth_fifo_pos>=AUTH_FIFO_SIZE)
- auth_fifo_pos=0;
-
- auth_fifo[auth_fifo_pos].account_id=account.account_id;
- auth_fifo[auth_fifo_pos].login_id1=account.login_id1;
- auth_fifo[auth_fifo_pos].login_id2=account.login_id2;
- auth_fifo[auth_fifo_pos].sex=account.sex;
- auth_fifo[auth_fifo_pos].delflag=0;
- auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr.sin_addr.s_addr;
- auth_fifo_pos++;
- }
- } else {
- char error[32];
-
- sprintf(tmpsql,"SELECT `error` FROM `errors` WHERE `result`='%d'",result);
- sql_query(tmpsql,"client_request_login");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
- if ((sql_row = mysql_fetch_row(sql_res))) {
- sprintf(error,sql_row[0]);
- } else {
- sprintf(error,"No Error!");
- }
- }
-
-
- sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', '%s', '%d','login failed : %s')", loginlog_db, p[0], p[1], p[2], p[3], t_uid, result, error);
-
-
- sql_query(tmpsql,"client_request_login");
-
- if ((result == 1) && (dynamic_pass_failure_ban != 0)){ // failed password
- sprintf(tmpsql,"SELECT count(*) FROM `%s` WHERE `ip` = '%d.%d.%d.%d' AND `rcode` = '1' AND `time` > NOW() - INTERVAL %d MINUTE",
- loginlog_db, p[0], p[1], p[2], p[3], dynamic_pass_failure_ban_time); //how many times filed account? in one ip.
- sql_query(tmpsql,"client_request_login");
-
- if ((sql_res = mysql_store_result(&mysql_handle))) {
- if ((sql_row = mysql_fetch_row(sql_res))) {
- if (atoi(sql_row[0]) >= dynamic_pass_failure_ban_how_many ) {
- sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() + INTERVAL %d MINUTE ,'Password error ban: %s')", p[0], p[1], p[2], dynamic_pass_failure_ban_how_long, t_uid);
- sql_query(tmpsql,"client_request_login");
- }
- }
- }
-
-
- mysql_free_result(sql_res);
-
- }
-
- //cannot connect login failed
- memset(WFIFOP(fd,0),'\0',23);
- WFIFOW(fd,0)=0x6a;
- WFIFOB(fd,2)=result-1;
- if (result == 6) { // 6 = Your are Prohibited to log in until %s
- char tmpstr[256];
- strftime(tmpstr, 20, date_format, localtime(&account.ban_until_time));
- tmpstr[19] = '\0';
- memcpy(WFIFOP(fd,3), tmpstr, 20);
- } else { // we send error message
- memcpy(WFIFOP(fd,3), error, 20);
- }
- }
-
- WFIFOSET(fd,23);
-
- RFIFOSKIP(fd,(RFIFOW(fd,0)==0x64)?55:47);
-
- return 0;
-}
-
-//------------------------------------------------------
-// MD5 Key requested for encypted login [Edit: Wizputer
-//------------------------------------------------------
-int md5_key_request(int fd, int len) {
- if (session[fd]->session_data) {
- #ifdef DEBUG
- printf("login: abnormal request of MD5 key (already opened session).\n");
- #endif
- session[fd]->eof = 1;
- return -1;
- }
-
- #ifdef DEBUG
- printf("Request Password key -%s\n",md5key);
- #endif
-
- RFIFOSKIP(fd,2);
- WFIFOW(fd,0)=0x01dc;
- WFIFOW(fd,2)=4+md5keylen;
- memcpy(WFIFOP(fd,4),md5key,md5keylen);
- WFIFOSET(fd,WFIFOW(fd,2));
-
- return 0;
-}
-
-//----------------------------------------------------
-// Char-server requesting connection [Edit: Wizputer]
-//-----------------------------------------------------
-int char_request_login(int fd, int len, unsigned char *p) {
- if(len<86)
- return -1;
-
- struct mmo_account account;
- unsigned char* server_name;
- char t_uid[32];
- int result;
-
- sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', '%s@%s','100', 'charserver - %s@%d.%d.%d.%d:%d')", loginlog_db, p[0], p[1], p[2], p[3], RFIFOP(fd, 2),RFIFOP(fd, 60),RFIFOP(fd, 60), RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58));
- sql_query(tmpsql,"char_request_login");
-
- #ifdef DEBUG
- printf("server connection request %s @ %d.%d.%d.%d:%d (%d.%d.%d.%d)\n",
- RFIFOP(fd, 60), RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58),
- p[0], p[1], p[2], p[3]);
- #endif
-
- account.userid = RFIFOP(fd, 2);
- account.passwd = RFIFOP(fd, 26);
- account.passwdenc = 0;
- server_name = RFIFOP(fd,60);
- result = mmo_auth(&account, fd);
-
- #ifdef DEBUG
- printf("Result: %d - Sex: %d - Account ID: %d\n",result,account.sex,(int) account.account_id);
- #endif
-
- if(result == -1 && account.sex==2 && account.account_id<MAX_SERVERS && server_fd[account.account_id]==-1){
- printf("Connection of the char-server '%s' accepted.\n", server_name);
-
- memset(&server[account.account_id], 0, sizeof(struct mmo_char_server));
-
- server[account.account_id].ip=RFIFOL(fd,54);
- server[account.account_id].port=RFIFOW(fd,58);
- memcpy(server[account.account_id].name,RFIFOP(fd,60),20);
- server[account.account_id].users=0;
- server[account.account_id].maintenance=RFIFOW(fd,82);
- server[account.account_id].new=RFIFOW(fd,84);
- server_fd[account.account_id]=fd;
-
- if(anti_freeze_enable)
- server_freezeflag[account.account_id] = 5; // Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed
-
- jstrescapecpy(t_uid,server[account.account_id].name);
-
- sprintf(tmpsql,"REPLACE DELAYED INTO `sstatus`(`index`,`name`,`user`) VALUES ( '%ld', '%s', '%d')",
- account.account_id, server[account.account_id].name,0);
- sql_query(tmpsql,"char_request_login");
-
- WFIFOW(fd,0)=0x2711;
- WFIFOB(fd,2)=0;
- WFIFOSET(fd,3);
- session[fd]->func_parse=parse_fromchar;
- realloc_fifo(fd,FIFOSIZE_SERVERLINK,FIFOSIZE_SERVERLINK);
-
- servers_connected++;
- } else {
- WFIFOW(fd, 0) =0x2711;
- WFIFOB(fd, 2)=3;
- WFIFOSET(fd, 3);
- }
-
- RFIFOSKIP(fd, 86);
-
- return 0;
-}
-
-//---------------------------------------------
-// Athena Version Info Request [Edit: Wizputer]
-//---------------------------------------------
-int request_athena_info(int fd, int len) {
- #ifdef DEBUG
- printf ("Athena version check...\n");
- #endif
-
- WFIFOW(fd,0)=0x7531;
- WFIFOB(fd,2)=ATHENA_MAJOR_VERSION;
- WFIFOB(fd,3)=ATHENA_MINOR_VERSION;
- WFIFOB(fd,4)=ATHENA_REVISION;
- WFIFOB(fd,5)=ATHENA_RELEASE_FLAG;
- WFIFOB(fd,6)=ATHENA_OFFICIAL_FLAG;
- WFIFOB(fd,7)=ATHENA_SERVER_LOGIN;
- WFIFOW(fd,8)=ATHENA_MOD_VERSION;
- WFIFOSET(fd,10);
- RFIFOSKIP(fd,2);
-
- return 0;
-}
-
-//----------------------------------------------------------------------------------------
-// Default packet parsing (normal players or administation/char-server connection requests)
-//----------------------------------------------------------------------------------------
-int parse_login(int fd) {
- char ip[16];
- int len,res=0;
-
- unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
- sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
-
- if (ipban > 0) {
- //ip ban
- //p[0], p[1], p[2], p[3]
- //request DB connection
- //check
- sprintf(tmpsql, "SELECT count(*) FROM `ipbanlist` WHERE `list` = '%d.*.*.*' OR `list` = '%d.%d.*.*' OR `list` = '%d.%d.%d.*' OR `list` = '%d.%d.%d.%d'",
- p[0], p[0], p[1], p[0], p[1], p[2], p[0], p[1], p[2], p[3]);
- sql_query(tmpsql,"parse_login");
-
- if((sql_res = mysql_store_result(&mysql_handle))) {
- if((sql_row = mysql_fetch_row(sql_res))) {//row fetching
- if (atoi(sql_row[0]) >0) {
- // ip ban ok.
- printf ("packet from banned ip : %d.%d.%d.%d" RETCODE, p[0], p[1], p[2], p[3]);
-
- sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', 'unknown','-3', 'ip banned')", loginlog_db, p[0], p[1], p[2], p[3]);
- sql_query(tmpsql,"parse_login");
-
- #ifdef DEBUG
- printf ("close session connection...\n");
- #endif
-
- // close connection
- session[fd]->eof = 1;
- } else {
- #ifdef DEBUG
- printf ("packet from ip (ban check ok) : %d.%d.%d.%d" RETCODE, p[0], p[1], p[2], p[3]);
- #endif
- }
- }
- }
-
- mysql_free_result(sql_res);
- }
-
- if (session[fd]->eof) {
- int i;
- for(i = 0; i < MAX_SERVERS && i < servers_connected; i++)
- if (server_fd[i] == fd) {
- server_fd[i] = -1;
- servers_connected--;
- }
- close(fd);
- delete_session(fd);
- return 0;
- }
-
- len = RFIFOREST(fd);
-
- while(len>=2 && res == 0){
- #ifdef DEBUG_PACKETS
- printf("parse_login : %d %d packet case=%x\n", fd, RFIFOREST(fd), RFIFOW(fd,0));
- #endif
-
- switch(RFIFOW(fd,0)){
- case 0x200: // New alive packet: structure: 0x200 <account.userid>.24B. used to verify if client is always alive.
- if (RFIFOREST(fd) < 26)
- return 0;
- RFIFOSKIP(fd,26);
- break;
-
- case 0x204: // New alive packet: structure: 0x204 <encrypted.account.userid>.16B. (new ragexe from 22 june 2004)
- if (RFIFOREST(fd) < 18)
- return 0;
- RFIFOSKIP(fd,18);
- break;
-
- case 0x64:
- case 0x01dd: res = client_request_login(fd,len,p); break;
- case 0x01db: res = md5_key_request(fd,len); break;
- case 0x2710: res = char_request_login(fd,len,p); break;
- case 0x7530: res = request_athena_info(fd,len); break;
-
- case 0x7532:
- default:
- #ifdef DEBUG
- printf ("End of connection (ip: %s)" RETCODE, ip);
- #endif
- session[fd]->eof = 1;
- return 0;
- }
-
- len = RFIFOREST(fd);
- }
-
- return 0;
-}
-
diff --git a/src/login_sql/login_int.h b/src/login_sql/login_int.h
deleted file mode 100644
index 712585616..000000000
--- a/src/login_sql/login_int.h
+++ /dev/null
@@ -1 +0,0 @@
-int parse_login(int);
diff --git a/src/login_sql/md5calc.c b/src/login_sql/md5calc.c
index 58cea1246..856c7ecb0 100644
--- a/src/login_sql/md5calc.c
+++ b/src/login_sql/md5calc.c
@@ -95,7 +95,7 @@ static void MD5_Round_Calculate(const unsigned char *block,
//Save A as AA, B as BB, C as CC, and and D as DD (saving of A, B, C, and D)
unsigned int A=*A2, B=*B2, C=*C2, D=*D2;
unsigned int AA = A,BB = B,CC = C,DD = D;
-
+
//It is a large region variable reluctantly because of calculation of a round. . . for Round1...4
pX = X;
@@ -186,7 +186,7 @@ void MD5_String2binary(const char * string, char * output)
memset(padding_message+copy_len, 0, 64 - copy_len); //It buries by 0 until it becomes extended bit length.
padding_message[copy_len] |= 0x80; //The next of a message is 1.
- //1-4
+ //1-4
//If 56 bytes or more (less than 64 bytes) of remainder becomes, it will calculate by extending to 64 bytes.
if (56 <= copy_len) {
MD5_Round_Calculate(padding_message, A,B,C,D);
@@ -225,7 +225,7 @@ void MD5_String(const char * string, char * output)
{
unsigned char digest[16];
- MD5_String2binary(string,digest);
+ MD5_String2binary(string,(char*)digest);
sprintf(output,
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
digest[ 0], digest[ 1], digest[ 2], digest[ 3],
diff --git a/src/login_sql/strlib.c b/src/login_sql/strlib.c
deleted file mode 100644
index fd8c90ef0..000000000
--- a/src/login_sql/strlib.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "strlib.h"
-#include "utils.h"
-
-//-----------------------------------------------
-// string lib.
-unsigned char* jstrescape (unsigned char* pt) {
- //copy from here
- unsigned char * ptr;
- int i =0, j=0;
-
- //copy string to temporary
- CREATE(ptr, char, J_MAX_MALLOC_SIZE);
- strcpy (ptr,pt);
-
- while (ptr[i] != '\0') {
- switch (ptr[i]) {
- case '\'':
- pt[j++] = '\\';
- pt[j++] = ptr[i++];
- break;
- case '\\':
- pt[j++] = '\\';
- pt[j++] = ptr[i++];
- break;
- default:
- pt[j++] = ptr[i++];
- }
- }
- pt[j++] = '\0';
- if(ptr) free(ptr);
- return (unsigned char*) &pt[0];
-}
-
-unsigned char* jstrescapecpy (unsigned char* pt,unsigned char* spt) {
- //copy from here
- int i =0, j=0;
-
- while (spt[i] != '\0') {
- switch (spt[i]) {
- case '\'':
- pt[j++] = '\\';
- pt[j++] = spt[i++];
- break;
- case '\\':
- pt[j++] = '\\';
- pt[j++] = spt[i++];
- break;
- default:
- pt[j++] = spt[i++];
- }
- }
- pt[j++] = '\0';
- return (unsigned char*) &pt[0];
-}
diff --git a/src/map/GNUmakefile b/src/map/GNUmakefile
deleted file mode 100644
index 03f520f37..000000000
--- a/src/map/GNUmakefile
+++ /dev/null
@@ -1,75 +0,0 @@
-all: txt sql
-
-txt: txtobj map-server
-
-sql: sqlobj map-server_sql
-
-txtobj:
- mkdir txtobj
-
-sqlobj:
- mkdir sqlobj
-
-COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/grfio.o ../common/db.o ../common/lock.o ../common/nullpo.o ../common/malloc.o ../common/showmsg.o
-LIBS = -lz -lm
-
-map-server: txtobj/map.o txtobj/chrif.o txtobj/clif.o txtobj/pc.o txtobj/npc.o txtobj/chat.o txtobj/path.o txtobj/itemdb.o txtobj/mob.o txtobj/script.o txtobj/storage.o txtobj/skill.o txtobj/atcommand.o txtobj/charcommand.o txtobj/battle.o txtobj/intif.o txtobj/trade.o txtobj/party.o txtobj/vending.o txtobj/guild.o txtobj/pet.o $(COMMON_OBJ)
- $(CC) -o ../../$@ $^ $(LIBS)
-
-map-server_sql: sqlobj/map.o sqlobj/chrif.o sqlobj/clif.o sqlobj/pc.o sqlobj/npc.o sqlobj/chat.o sqlobj/path.o sqlobj/itemdb.o sqlobj/mob.o sqlobj/script.o sqlobj/storage.o sqlobj/skill.o sqlobj/atcommand.o sqlobj/charcommand.o sqlobj/battle.o sqlobj/intif.o sqlobj/trade.o sqlobj/party.o sqlobj/vending.o sqlobj/guild.o sqlobj/pet.o sqlobj/mail.o sqlobj/log.o $(COMMON_OBJ)
- $(CC) -o ../../$@ $^ $(LIB_S)
-
-txtobj/%.o: %.c
- $(COMPILE.c) -DTXT_ONLY $(OUTPUT_OPTION) $<
-
-sqlobj/%.o: %.c
- $(COMPILE.c) $(OUTPUT_OPTION) $<
-
-txtobj/map.o: map.c map.h chrif.h clif.h npc.h pc.h mob.h chat.h skill.h itemdb.h storage.h party.h pet.h atcommand.h ../common/core.h ../common/timer.h ../common/db.h ../common/grfio.h ../common/mmo.h ../common/showmsg.h
-txtobj/chrif.o: chrif.c map.h battle.h chrif.h clif.h intif.h pc.h npc.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-txtobj/clif.o: clif.c map.h chrif.h clif.h mob.h intif.h pc.h npc.h itemdb.h chat.h script.h storage.h party.h guild.h atcommand.h pet.h charcommand.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/showmsg.h
-txtobj/pc.o: pc.c map.h clif.h intif.h pc.h npc.h mob.h itemdb.h battle.h skill.h script.h party.h guild.h pet.h trade.h storage.h chat.h vending.h ../common/timer.h ../common/mmo.h ../common/db.h ../common/showmsg.h
-txtobj/npc.o: npc.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h ../common/db.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-txtobj/chat.o: chat.c map.h clif.h pc.h chat.h ../common/db.h ../common/mmo.h ../common/showmsg.h
-txtobj/path.o: path.c map.h battle.h ../common/mmo.h ../common/showmsg.h
-txtobj/itemdb.o: itemdb.c map.h battle.h itemdb.h ../common/db.h ../common/grfio.h ../common/mmo.h ../common/showmsg.h
-txtobj/mob.o: mob.c map.h clif.h intif.h pc.h mob.h skill.h battle.h npc.h itemdb.h ../common/timer.h ../common/socket.h ../common/mmo.h ../common/showmsg.h
-txtobj/script.o: script.c itemdb.h map.h pc.h mob.h clif.h intif.h npc.h script.h storage.h skill.h pet.h battle.h ../common/timer.h ../common/socket.h ../common/db.h ../common/mmo.h ../common/lock.h ../common/showmsg.h
-txtobj/storage.o: storage.c itemdb.h pc.h clif.h intif.h storage.h guild.h ../common/mmo.h ../common/db.h ../common/showmsg.h
-txtobj/skill.o: skill.c skill.h map.h clif.h pc.h mob.h battle.h itemdb.h script.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-txtobj/atcommand.o: atcommand.c atcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-txtobj/battle.o: battle.c battle.h skill.h map.h mob.h pc.h pet.h guild.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-txtobj/intif.o: intif.c intif.h chrif.h clif.h party.h guild.h storage.h map.h battle.h pet.h ../common/socket.h ../common/mmo.h ../common/showmsg.h
-txtobj/trade.o: trade.c trade.h clif.h itemdb.h map.h pc.h npc.h ../common/mmo.h ../common/showmsg.h
-txtobj/party.o: party.c party.h clif.h intif.h pc.h map.h battle.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-txtobj/vending.o: vending.c vending.h clif.h itemdb.h map.h pc.h ../common/mmo.h ../common/showmsg.h
-txtobj/guild.o: guild.c guild.h storage.h battle.h clif.h intif.h pc.h npc.h map.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-txtobj/pet.o: pet.c pet.h map.h clif.h chrif.h intif.h pc.h itemdb.h battle.h mob.h npc.h script.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-txtobj/charcommand.o: charcommand.c charcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-
-sqlobj/map.o: map.c map.h chrif.h clif.h npc.h pc.h mob.h chat.h skill.h itemdb.h storage.h party.h pet.h atcommand.h log.h ../common/core.h ../common/timer.h ../common/db.h ../common/grfio.h ../common/mmo.h ../common/showmsg.h
-sqlobj/chrif.o: chrif.c map.h battle.h chrif.h clif.h intif.h pc.h npc.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-sqlobj/clif.o: clif.c map.h chrif.h clif.h mob.h intif.h pc.h npc.h itemdb.h chat.h script.h storage.h party.h guild.h atcommand.h pet.h charcommand.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/showmsg.h
-sqlobj/pc.o: pc.c map.h clif.h intif.h pc.h npc.h mob.h itemdb.h battle.h skill.h script.h party.h guild.h pet.h trade.h storage.h chat.h vending.h log.h ../common/timer.h ../common/mmo.h ../common/db.h ../common/showmsg.h
-sqlobj/npc.o: npc.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h ../common/db.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-sqlobj/chat.o: chat.c map.h clif.h pc.h chat.h ../common/db.h ../common/mmo.h ../common/showmsg.h
-sqlobj/path.o: path.c map.h battle.h ../common/mmo.h ../common/showmsg.h
-sqlobj/itemdb.o: itemdb.c map.h battle.h itemdb.h ../common/db.h ../common/grfio.h ../common/mmo.h ../common/showmsg.h
-sqlobj/mob.o: mob.c map.h clif.h intif.h pc.h mob.h skill.h battle.h npc.h itemdb.h log.h ../common/timer.h ../common/socket.h ../common/mmo.h ../common/showmsg.h
-sqlobj/script.o: script.c itemdb.h map.h pc.h mob.h clif.h intif.h npc.h script.h storage.h skill.h pet.h battle.h log.h ../common/timer.h ../common/socket.h ../common/db.h ../common/mmo.h ../common/lock.h ../common/showmsg.h
-sqlobj/storage.o: storage.c itemdb.h pc.h clif.h intif.h storage.h guild.h ../common/mmo.h ../common/db.h ../common/showmsg.h
-sqlobj/skill.o: skill.c skill.h map.h clif.h pc.h mob.h battle.h itemdb.h script.h log.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-sqlobj/atcommand.o: atcommand.c atcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-sqlobj/battle.o: battle.c battle.h skill.h map.h mob.h pc.h pet.h guild.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-sqlobj/intif.o: intif.c intif.h chrif.h clif.h party.h guild.h storage.h map.h battle.h pet.h ../common/socket.h ../common/mmo.h ../common/showmsg.h
-sqlobj/trade.o: trade.c trade.h clif.h itemdb.h map.h pc.h npc.h log.h ../common/mmo.h ../common/showmsg.h
-sqlobj/party.o: party.c party.h clif.h intif.h pc.h map.h battle.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-sqlobj/vending.o: vending.c vending.h clif.h itemdb.h map.h pc.h log.h ../common/mmo.h ../common/showmsg.h
-sqlobj/guild.o: guild.c guild.h storage.h battle.h clif.h intif.h pc.h npc.h map.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-sqlobj/pet.o: pet.c pet.h map.h clif.h chrif.h intif.h pc.h itemdb.h battle.h mob.h npc.h script.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-sqlobj/mail.o: mail.c mail.h ../common/showmsg.h
-sqlobj/log.o: log.c log.h map.h ../common/nullpo.h
-sqlobj/charcommand.o: charcommand.c charcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-
-clean:
- rm -rf *.o ../../map-server ../../map-server_sql sqlobj txtobj
diff --git a/src/map/Makefile b/src/map/Makefile
index 4786887ae..b413c8a62 100644
--- a/src/map/Makefile
+++ b/src/map/Makefile
@@ -10,13 +10,15 @@ txtobj:
sqlobj:
mkdir sqlobj
-COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/grfio.o ../common/db.o ../common/lock.o ../common/nullpo.o ../common/malloc.o ../common/showmsg.o
+COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o ../common/obj/grfio.o ../common/obj/db.o ../common/obj/lock.o ../common/obj/nullpo.o ../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/utils.o ../common/obj/strlib.o
+
+COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/grfio.h ../common/db.h ../common/lock.h ../common/nullpo.h ../common/malloc.h ../common/showmsg.h ../common/utils.h ../common/strlib.h
LIBS = -lz -lm
-map-server: txtobj/map.o txtobj/chrif.o txtobj/clif.o txtobj/pc.o txtobj/npc.o txtobj/chat.o txtobj/path.o txtobj/itemdb.o txtobj/mob.o txtobj/script.o txtobj/storage.o txtobj/skill.o txtobj/atcommand.o txtobj/charcommand.o txtobj/battle.o txtobj/intif.o txtobj/trade.o txtobj/party.o txtobj/vending.o txtobj/guild.o txtobj/pet.o $(COMMON_OBJ)
- $(CC) -o ../../$@ $> $(LIBS)
+map-server: txtobj/map.o txtobj/chrif.o txtobj/clif.o txtobj/pc.o txtobj/status.o txtobj/npc.o txtobj/npc_chat.o txtobj/chat.o txtobj/path.o txtobj/itemdb.o txtobj/mob.o txtobj/script.o txtobj/storage.o txtobj/skill.o txtobj/atcommand.o txtobj/charcommand.o txtobj/battle.o txtobj/intif.o txtobj/trade.o txtobj/party.o txtobj/vending.o txtobj/guild.o txtobj/pet.o txtobj/log.o $(COMMON_OBJ)
+ $(CC) -o ../../$@ $> $(LIBS) $(LIB_S)
-map-server_sql: sqlobj/map.o sqlobj/chrif.o sqlobj/clif.o sqlobj/pc.o sqlobj/npc.o sqlobj/chat.o sqlobj/path.o sqlobj/itemdb.o sqlobj/mob.o sqlobj/script.o sqlobj/storage.o sqlobj/skill.o sqlobj/atcommand.o sqlobj/charcommand.o sqlobj/battle.o sqlobj/intif.o sqlobj/trade.o sqlobj/party.o sqlobj/vending.o sqlobj/guild.o sqlobj/pet.o sqlobj/mail.o sqlobj/log.o $(COMMON_OBJ)
+map-server_sql: sqlobj/map.o sqlobj/chrif.o sqlobj/clif.o sqlobj/pc.o sqlobj/status.o sqlobj/npc.o sqlobj/npc_chat.o sqlobj/chat.o sqlobj/path.o sqlobj/itemdb.o sqlobj/mob.o sqlobj/script.o sqlobj/storage.o sqlobj/skill.o sqlobj/atcommand.o sqlobj/charcommand.o sqlobj/battle.o sqlobj/intif.o sqlobj/trade.o sqlobj/party.o sqlobj/vending.o sqlobj/guild.o sqlobj/pet.o sqlobj/mail.o sqlobj/log.o $(COMMON_OBJ)
$(CC) -o ../../$@ $> $(LIB_S)
txtobj/%.o: %.c
@@ -25,51 +27,56 @@ txtobj/%.o: %.c
sqlobj/%.o: %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
-txtobj/map.o: map.c map.h chrif.h clif.h npc.h pc.h mob.h chat.h skill.h itemdb.h storage.h party.h pet.h atcommand.h ../common/core.h ../common/timer.h ../common/db.h ../common/grfio.h ../common/mmo.h ../common/showmsg.h
-txtobj/chrif.o: chrif.c map.h battle.h chrif.h clif.h intif.h pc.h npc.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-txtobj/clif.o: clif.c map.h chrif.h clif.h mob.h intif.h pc.h npc.h itemdb.h chat.h script.h storage.h party.h guild.h atcommand.h pet.h charcommand.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/showmsg.h
-txtobj/pc.o: pc.c map.h clif.h intif.h pc.h npc.h mob.h itemdb.h battle.h skill.h script.h party.h guild.h pet.h trade.h storage.h chat.h vending.h ../common/timer.h ../common/mmo.h ../common/db.h ../common/showmsg.h
-txtobj/npc.o: npc.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h ../common/db.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-txtobj/chat.o: chat.c map.h clif.h pc.h chat.h ../common/db.h ../common/mmo.h ../common/showmsg.h
-txtobj/path.o: path.c map.h battle.h ../common/mmo.h ../common/showmsg.h
-txtobj/itemdb.o: itemdb.c map.h battle.h itemdb.h ../common/db.h ../common/grfio.h ../common/mmo.h ../common/showmsg.h
-txtobj/mob.o: mob.c map.h clif.h intif.h pc.h mob.h skill.h battle.h npc.h itemdb.h ../common/timer.h ../common/socket.h ../common/mmo.h ../common/showmsg.h
-txtobj/script.o: script.c itemdb.h map.h pc.h mob.h clif.h intif.h npc.h script.h storage.h skill.h pet.h battle.h ../common/timer.h ../common/socket.h ../common/db.h ../common/mmo.h ../common/lock.h ../common/showmsg.h
-txtobj/storage.o: storage.c itemdb.h pc.h clif.h intif.h storage.h guild.h ../common/mmo.h ../common/db.h ../common/showmsg.h
-txtobj/skill.o: skill.c skill.h map.h clif.h pc.h mob.h battle.h itemdb.h script.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-txtobj/atcommand.o: atcommand.c atcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-txtobj/battle.o: battle.c battle.h skill.h map.h mob.h pc.h pet.h guild.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-txtobj/intif.o: intif.c intif.h chrif.h clif.h party.h guild.h storage.h map.h battle.h pet.h ../common/socket.h ../common/mmo.h ../common/showmsg.h
-txtobj/trade.o: trade.c trade.h clif.h itemdb.h map.h pc.h npc.h ../common/mmo.h ../common/showmsg.h
-txtobj/party.o: party.c party.h clif.h intif.h pc.h map.h battle.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-txtobj/vending.o: vending.c vending.h clif.h itemdb.h map.h pc.h ../common/mmo.h ../common/showmsg.h
-txtobj/guild.o: guild.c guild.h storage.h battle.h clif.h intif.h pc.h npc.h map.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-txtobj/pet.o: pet.c pet.h map.h clif.h chrif.h intif.h pc.h itemdb.h battle.h mob.h npc.h script.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-txtobj/charcommand.o: charcommand.c charcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
+txtobj/map.o: map.c map.h chrif.h clif.h npc.h pc.h mob.h chat.h skill.h itemdb.h storage.h party.h pet.h atcommand.h $(COMMON_H)
+txtobj/chrif.o: chrif.c map.h battle.h chrif.h clif.h intif.h pc.h npc.h $(COMMON_H)
+txtobj/clif.o: clif.c map.h chrif.h clif.h mob.h intif.h pc.h npc.h itemdb.h chat.h script.h storage.h party.h guild.h atcommand.h pet.h charcommand.h $(COMMON_H)
+txtobj/pc.o: pc.c map.h clif.h intif.h pc.h npc.h mob.h itemdb.h battle.h skill.h script.h party.h guild.h pet.h trade.h storage.h chat.h vending.h $(COMMON_H)
+txtobj/status.o: status.c pc.h map.h clif.h status.h mob.h itemdb.h battle.h skill.h script.h pet.h guild.h $(COMMON_H)
+txtobj/npc.o: npc.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h $(COMMON_H)
+txtobj/npc_chat.o: npc_chat.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h $(COMMON_H)
+txtobj/chat.o: chat.c map.h clif.h pc.h chat.h $(COMMON_H)
+txtobj/path.o: path.c map.h battle.h $(COMMON_H)
+txtobj/itemdb.o: itemdb.c map.h battle.h itemdb.h $(COMMON_H)
+txtobj/mob.o: mob.c map.h clif.h intif.h pc.h mob.h skill.h battle.h npc.h itemdb.h $(COMMON_H)
+txtobj/script.o: script.c itemdb.h map.h pc.h mob.h clif.h intif.h npc.h script.h storage.h skill.h pet.h battle.h log.h $(COMMON_H)
+txtobj/storage.o: storage.c itemdb.h pc.h clif.h intif.h storage.h guild.h $(COMMON_H)
+txtobj/skill.o: skill.c skill.h map.h clif.h pc.h mob.h battle.h itemdb.h script.h $(COMMON_H)
+txtobj/atcommand.o: atcommand.c atcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h $(COMMON_H)
+txtobj/battle.o: battle.c battle.h skill.h map.h mob.h pc.h pet.h guild.h $(COMMON_H)
+txtobj/intif.o: intif.c intif.h chrif.h clif.h party.h guild.h storage.h map.h battle.h pet.h $(COMMON_H)
+txtobj/trade.o: trade.c trade.h clif.h itemdb.h map.h pc.h npc.h $(COMMON_H)
+txtobj/party.o: party.c party.h clif.h intif.h pc.h map.h battle.h $(COMMON_H)
+txtobj/vending.o: vending.c vending.h clif.h itemdb.h map.h pc.h $(COMMON_H)
+txtobj/guild.o: guild.c guild.h storage.h battle.h clif.h intif.h pc.h npc.h map.h $(COMMON_H)
+txtobj/pet.o: pet.c pet.h map.h clif.h chrif.h intif.h pc.h itemdb.h battle.h mob.h npc.h script.h $(COMMON_H)
+txtobj/log.o: log.c log.h map.h $(COMMON_H)
+txtobj/charcommand.o: charcommand.c charcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h $(COMMON_H)
-sqlobj/map.o: map.c map.h chrif.h clif.h npc.h pc.h mob.h chat.h skill.h itemdb.h storage.h party.h pet.h atcommand.h log.h ../common/core.h ../common/timer.h ../common/db.h ../common/grfio.h ../common/mmo.h ../common/showmsg.h
-sqlobj/chrif.o: chrif.c map.h battle.h chrif.h clif.h intif.h pc.h npc.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-sqlobj/clif.o: clif.c map.h chrif.h clif.h mob.h intif.h pc.h npc.h itemdb.h chat.h script.h storage.h party.h guild.h atcommand.h pet.h charcommand.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/showmsg.h
-sqlobj/pc.o: pc.c map.h clif.h intif.h pc.h npc.h mob.h itemdb.h battle.h skill.h script.h party.h guild.h pet.h trade.h storage.h chat.h vending.h log.h ../common/timer.h ../common/mmo.h ../common/db.h ../common/showmsg.h
-sqlobj/npc.o: npc.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h ../common/db.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-sqlobj/chat.o: chat.c map.h clif.h pc.h chat.h ../common/db.h ../common/mmo.h ../common/showmsg.h
-sqlobj/path.o: path.c map.h battle.h ../common/mmo.h ../common/showmsg.h
-sqlobj/itemdb.o: itemdb.c map.h battle.h itemdb.h ../common/db.h ../common/grfio.h ../common/mmo.h ../common/showmsg.h
-sqlobj/mob.o: mob.c map.h clif.h intif.h pc.h mob.h skill.h battle.h npc.h itemdb.h log.h ../common/timer.h ../common/socket.h ../common/mmo.h ../common/showmsg.h
-sqlobj/script.o: script.c itemdb.h map.h pc.h mob.h clif.h intif.h npc.h script.h storage.h skill.h pet.h battle.h log.h ../common/timer.h ../common/socket.h ../common/db.h ../common/mmo.h ../common/lock.h ../common/showmsg.h
-sqlobj/storage.o: storage.c itemdb.h pc.h clif.h intif.h storage.h guild.h ../common/mmo.h ../common/db.h ../common/showmsg.h
-sqlobj/skill.o: skill.c skill.h map.h clif.h pc.h mob.h battle.h itemdb.h script.h log.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-sqlobj/atcommand.o: atcommand.c atcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-sqlobj/battle.o: battle.c battle.h skill.h map.h mob.h pc.h pet.h guild.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-sqlobj/intif.o: intif.c intif.h chrif.h clif.h party.h guild.h storage.h map.h battle.h pet.h ../common/socket.h ../common/mmo.h ../common/showmsg.h
-sqlobj/trade.o: trade.c trade.h clif.h itemdb.h map.h pc.h npc.h log.h ../common/mmo.h ../common/showmsg.h
-sqlobj/party.o: party.c party.h clif.h intif.h pc.h map.h battle.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-sqlobj/vending.o: vending.c vending.h clif.h itemdb.h map.h pc.h log.h ../common/mmo.h ../common/showmsg.h
-sqlobj/guild.o: guild.c guild.h storage.h battle.h clif.h intif.h pc.h npc.h map.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-sqlobj/pet.o: pet.c pet.h map.h clif.h chrif.h intif.h pc.h itemdb.h battle.h mob.h npc.h script.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-sqlobj/mail.o: mail.c mail.h ../common/showmsg.h
-sqlobj/log.o: log.c log.h map.h ../common/nullpo.h
-sqlobj/charcommand.o: charcommand.c charcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
+sqlobj/map.o: map.c map.h chrif.h clif.h npc.h pc.h mob.h chat.h skill.h itemdb.h storage.h party.h pet.h atcommand.h log.h $(COMMON_H)
+sqlobj/chrif.o: chrif.c map.h battle.h chrif.h clif.h intif.h pc.h npc.h $(COMMON_H)
+sqlobj/clif.o: clif.c map.h chrif.h clif.h mob.h intif.h pc.h npc.h itemdb.h chat.h script.h storage.h party.h guild.h atcommand.h pet.h charcommand.h $(COMMON_H)
+sqlobj/pc.o: pc.c map.h clif.h intif.h pc.h npc.h mob.h itemdb.h battle.h skill.h script.h party.h guild.h pet.h trade.h storage.h chat.h vending.h log.h $(COMMON_H)
+sqlobj/status.o: status.c pc.h map.h clif.h status.h mob.h itemdb.h battle.h skill.h script.h pet.h guild.h $(COMMON_H)
+sqlobj/npc.o: npc.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h $(COMMON_H)
+sqlobj/npc_chat.o: npc_chat.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h $(COMMON_H)
+sqlobj/chat.o: chat.c map.h clif.h pc.h chat.h $(COMMON_H)
+sqlobj/path.o: path.c map.h battle.h $(COMMON_H)
+sqlobj/itemdb.o: itemdb.c map.h battle.h itemdb.h $(COMMON_H)
+sqlobj/mob.o: mob.c map.h clif.h intif.h pc.h mob.h skill.h battle.h npc.h itemdb.h log.h $(COMMON_H)
+sqlobj/script.o: script.c itemdb.h map.h pc.h mob.h clif.h intif.h npc.h script.h storage.h skill.h pet.h battle.h log.h $(COMMON_H)
+sqlobj/storage.o: storage.c itemdb.h pc.h clif.h intif.h storage.h guild.h $(COMMON_H)
+sqlobj/skill.o: skill.c skill.h map.h clif.h pc.h mob.h battle.h itemdb.h script.h log.h $(COMMON_H)
+sqlobj/atcommand.o: atcommand.c atcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h $(COMMON_H)
+sqlobj/battle.o: battle.c battle.h skill.h map.h mob.h pc.h pet.h guild.h $(COMMON_H)
+sqlobj/intif.o: intif.c intif.h chrif.h clif.h party.h guild.h storage.h map.h battle.h pet.h $(COMMON_H)
+sqlobj/trade.o: trade.c trade.h clif.h itemdb.h map.h pc.h npc.h log.h $(COMMON_H)
+sqlobj/party.o: party.c party.h clif.h intif.h pc.h map.h battle.h $(COMMON_H)
+sqlobj/vending.o: vending.c vending.h clif.h itemdb.h map.h pc.h log.h $(COMMON_H)
+sqlobj/guild.o: guild.c guild.h storage.h battle.h clif.h intif.h pc.h npc.h map.h $(COMMON_H)
+sqlobj/pet.o: pet.c pet.h map.h clif.h chrif.h intif.h pc.h itemdb.h battle.h mob.h npc.h script.h $(COMMON_H)
+sqlobj/mail.o: mail.c mail.h $(COMMON_H)
+sqlobj/log.o: log.c log.h map.h $(COMMON_H)
+sqlobj/charcommand.o: charcommand.c charcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h $(COMMON_H)
clean:
rm -rf *.o ../../map-server ../../map-server_sql sqlobj txtobj
diff --git a/src/map/Makefile.win32 b/src/map/Makefile.win32
index ed4b4e95a..2fa1861ac 100644
--- a/src/map/Makefile.win32
+++ b/src/map/Makefile.win32
@@ -15,25 +15,28 @@ txtobj:
sqlobj:
mkdir sqlobj
-ZLIBDIR = C:/eathena/zlib122
-PACKETDEF = -DPACKETVER=5 -DNEW_006b -D__WIN32
+ZLIBDIR = ../zlib
+PACKETDEF = -DPACKETVER=6 -DNEW_006b -D__WIN32 -DLOCALZLIB
# OPT = /MDd /D_DEBUG
OPT =
LINKOPT = /debug /SUBSYSTEM:CONSOLE
# OPT = /O2
CFLAGS = $(OPT) /nologo /I../common /I$(ZLIBDIR) $(PACKETDEF) /D_WIN32
-COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/grfio.o ../common/db.o ../common/lock.o ../common/nullpo.o ../common/malloc.o ../common/showmsg.o
+COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/grfio.o ../common/db.o ../common/lock.o ../common/nullpo.o ../common/malloc.o ../common/showmsg.o ../common/strlib.o ../common/utils.o
+
LIBS = "WSOCK32.LIB"
# "WSOCK32.LIB" "USER32.LIB" "ADVAPI32.LIB" "MSVCRT.LIB" "OLDNAMES.LIB" "KERNEL32.LIB"
-TXTOBJS = txtobj/map.o txtobj/chrif.o txtobj/clif.o txtobj/pc.o txtobj/npc.o txtobj/chat.o txtobj/path.o txtobj/itemdb.o txtobj/mob.o txtobj/script.o txtobj/storage.o txtobj/skill.o txtobj/atcommand.o txtobj/battle.o txtobj/intif.o txtobj/trade.o txtobj/party.o txtobj/vending.o txtobj/guild.o txtobj/pet.o $(COMMON_OBJ) $(ZLIBDIR)/inflate.o $(ZLIBDIR)/adler32.o $(ZLIBDIR)/crc32.o $(ZLIBDIR)/inftrees.o $(ZLIBDIR)/zutil.o $(ZLIBDIR)/inffast.o
+TXTOBJS = txtobj/map.o txtobj/chrif.o txtobj/clif.o txtobj/pc.o txtobj/status.o txtobj/npc.o txtobj/npc_chat.o txtobj/chat.o txtobj/path.o txtobj/itemdb.o txtobj/mob.o txtobj/script.o txtobj/storage.o txtobj/skill.o txtobj/atcommand.o txtobj/charcommand.o txtobj/battle.o txtobj/intif.o txtobj/trade.o txtobj/party.o txtobj/vending.o txtobj/guild.o txtobj/pet.o txtobj/log.o $(COMMON_OBJ) $(ZLIBDIR)/inflate.o $(ZLIBDIR)/deflate.o $(ZLIBDIR)/trees.o $(ZLIBDIR)/adler32.o $(ZLIBDIR)/compress.o $(ZLIBDIR)/crc32.o $(ZLIBDIR)/inftrees.o $(ZLIBDIR)/zutil.o $(ZLIBDIR)/inffast.o
+
+SQLOBJS = sqlobj/map.o sqlobj/chrif.o sqlobj/clif.o sqlobj/pc.o sqlobj/status.o sqlobj/npc.o sqlobj/npc_chat.o sqlobj/chat.o sqlobj/path.o sqlobj/itemdb.o sqlobj/mob.o sqlobj/script.o sqlobj/storage.o sqlobj/skill.o sqlobj/atcommand.o sqlobj/charcommand.o sqlobj/battle.o sqlobj/intif.o sqlobj/trade.o sqlobj/party.o sqlobj/vending.o sqlobj/guild.o sqlobj/pet.o sqlobj/log.o $(COMMON_OBJ) $(ZLIBDIR)/inflate.o $(ZLIBDIR)/adler32.o $(ZLIBDIR)/crc32.o $(ZLIBDIR)/inftrees.o $(ZLIBDIR)/zutil.o $(ZLIBDIR)/inffast.o
map-server: $(TXTOBJS)
link $(LINKOPT) /out:../../$@.exe $(TXTOBJS) $(LIBS)
-map-server_sql: sqlobj/map.o sqlobj/chrif.o sqlobj/clif.o sqlobj/pc.o sqlobj/npc.o sqlobj/chat.o sqlobj/path.o sqlobj/itemdb.o sqlobj/mob.o sqlobj/script.o sqlobj/storage.o sqlobj/skill.o sqlobj/atcommand.o sqlobj/battle.o sqlobj/intif.o sqlobj/trade.o sqlobj/party.o sqlobj/vending.o sqlobj/guild.o sqlobj/pet.o sqlobj/mail.o $(COMMON_OBJ)
+map-server_sql: $(SQLOBJS)
link $(LINKOPT) /out:../../$@.exe $> $(LIBS)
txtobj/%.o: %.c
@@ -86,7 +89,7 @@ sqlobj/party.o: party.c party.h clif.h intif.h pc.h map.h battle.h ../common/db.
sqlobj/vending.o: vending.c vending.h clif.h itemdb.h map.h pc.h log.h ../common/mmo.h ../common/showmsg.h
sqlobj/guild.o: guild.c guild.h storage.h battle.h clif.h intif.h pc.h npc.h map.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
sqlobj/pet.o: pet.c pet.h map.h clif.h chrif.h intif.h pc.h itemdb.h battle.h mob.h npc.h script.h ../common/db.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
-sqlobj/mail.o: mail.c mail.h ../common/showmsg.h
+sqlobj/mail.o: mail.c mail.h ../common/showmsg.h ../common/strlib.h ../common/utils.h
sqlobj/log.o: log.c log.h map.h ../common/nullpo.h
clean:
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 34bf0150d..79e3ec675 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -8,6 +8,9 @@
#include "../common/socket.h"
#include "../common/timer.h"
#include "../common/nullpo.h"
+#include "../common/mmo.h"
+#include "../common/db.h"
+#include "../common/core.h"
#include "log.h"
#include "clif.h"
@@ -16,6 +19,7 @@
#include "itemdb.h"
#include "map.h"
#include "pc.h"
+#include "status.h"
#include "skill.h"
#include "mob.h"
#include "pet.h"
@@ -26,7 +30,6 @@
#include "script.h"
#include "npc.h"
#include "trade.h"
-#include "core.h"
#ifndef TXT_ONLY
#include "mail.h"
@@ -36,201 +39,233 @@
static char command_symbol = '@'; // first char of the commands (by [Yor])
-static char msg_table[1000][1024]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others)
-
-#define ATCOMMAND_FUNC(x) int atcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message)
-ATCOMMAND_FUNC(broadcast);
-ATCOMMAND_FUNC(localbroadcast);
-ATCOMMAND_FUNC(rurap);
-ATCOMMAND_FUNC(rura);
-ATCOMMAND_FUNC(where);
-ATCOMMAND_FUNC(jumpto);
-ATCOMMAND_FUNC(jump);
-ATCOMMAND_FUNC(who);
-ATCOMMAND_FUNC(who2);
-ATCOMMAND_FUNC(who3);
-ATCOMMAND_FUNC(whomap);
-ATCOMMAND_FUNC(whomap2);
-ATCOMMAND_FUNC(whomap3);
-ATCOMMAND_FUNC(whogm); // by Yor
-ATCOMMAND_FUNC(whozeny); // [Valaris]
-ATCOMMAND_FUNC(happyhappyjoyjoy); // [Valaris]
-ATCOMMAND_FUNC(save);
-ATCOMMAND_FUNC(load);
-ATCOMMAND_FUNC(speed);
-ATCOMMAND_FUNC(storage);
-ATCOMMAND_FUNC(guildstorage);
-ATCOMMAND_FUNC(option);
-ATCOMMAND_FUNC(hide);
-ATCOMMAND_FUNC(jobchange);
-ATCOMMAND_FUNC(die);
-ATCOMMAND_FUNC(kill);
-ATCOMMAND_FUNC(alive);
-ATCOMMAND_FUNC(kami);
-ATCOMMAND_FUNC(heal);
-ATCOMMAND_FUNC(item);
-ATCOMMAND_FUNC(item2);
-ATCOMMAND_FUNC(itemreset);
-ATCOMMAND_FUNC(itemcheck);
-ATCOMMAND_FUNC(baselevelup);
-ATCOMMAND_FUNC(joblevelup);
-ATCOMMAND_FUNC(help);
-ATCOMMAND_FUNC(gm);
-ATCOMMAND_FUNC(pvpoff);
-ATCOMMAND_FUNC(pvpon);
-ATCOMMAND_FUNC(gvgoff);
-ATCOMMAND_FUNC(gvgon);
-ATCOMMAND_FUNC(model);
-ATCOMMAND_FUNC(go);
-ATCOMMAND_FUNC(monster);
-ATCOMMAND_FUNC(monstersmall);
-ATCOMMAND_FUNC(monsterbig);
-ATCOMMAND_FUNC(spawn);
-ATCOMMAND_FUNC(killmonster);
-ATCOMMAND_FUNC(killmonster2);
-ATCOMMAND_FUNC(refine);
-ATCOMMAND_FUNC(produce);
-ATCOMMAND_FUNC(memo);
-ATCOMMAND_FUNC(gat);
-ATCOMMAND_FUNC(packet);
-ATCOMMAND_FUNC(statuspoint);
-ATCOMMAND_FUNC(skillpoint);
-ATCOMMAND_FUNC(zeny);
-ATCOMMAND_FUNC(param);
-ATCOMMAND_FUNC(guildlevelup);
-ATCOMMAND_FUNC(makeegg);
-ATCOMMAND_FUNC(hatch);
-ATCOMMAND_FUNC(petfriendly);
-ATCOMMAND_FUNC(pethungry);
-ATCOMMAND_FUNC(petrename);
-ATCOMMAND_FUNC(recall);
-ATCOMMAND_FUNC(recallall);
-ATCOMMAND_FUNC(revive);
-ATCOMMAND_FUNC(character_stats_all);
-ATCOMMAND_FUNC(character_save);
-ATCOMMAND_FUNC(night);
-ATCOMMAND_FUNC(day);
-ATCOMMAND_FUNC(doom);
-ATCOMMAND_FUNC(doommap);
-ATCOMMAND_FUNC(raise);
-ATCOMMAND_FUNC(raisemap);
-ATCOMMAND_FUNC(character_baselevel);
-ATCOMMAND_FUNC(character_joblevel);
-ATCOMMAND_FUNC(kick);
-ATCOMMAND_FUNC(kickall);
-ATCOMMAND_FUNC(allskill);
-ATCOMMAND_FUNC(questskill);
-ATCOMMAND_FUNC(charquestskill);
-ATCOMMAND_FUNC(lostskill);
-ATCOMMAND_FUNC(charlostskill);
-ATCOMMAND_FUNC(spiritball);
-ATCOMMAND_FUNC(party);
-ATCOMMAND_FUNC(guild);
-ATCOMMAND_FUNC(charskreset);
-ATCOMMAND_FUNC(charstreset);
-ATCOMMAND_FUNC(charreset);
-ATCOMMAND_FUNC(charstpoint);
-ATCOMMAND_FUNC(charmodel);
-ATCOMMAND_FUNC(charskpoint);
-ATCOMMAND_FUNC(charzeny);
-ATCOMMAND_FUNC(agitstart);
-ATCOMMAND_FUNC(agitend);
-ATCOMMAND_FUNC(reloaditemdb);
-ATCOMMAND_FUNC(reloadmobdb);
-ATCOMMAND_FUNC(reloadskilldb);
-#ifndef TXT_ONLY
-ATCOMMAND_FUNC(rehash);// by Fr3DBr
-#else /* TXT_ONLY */
-ATCOMMAND_FUNC(reloadscript);
-#endif /* TXT_ONLY */
-ATCOMMAND_FUNC(reloadgmdb); // by Yor
-ATCOMMAND_FUNC(mapexit);
-ATCOMMAND_FUNC(idsearch);
-ATCOMMAND_FUNC(mapinfo);
-ATCOMMAND_FUNC(dye); //** by fritz
-ATCOMMAND_FUNC(hair_style); //** by fritz
-ATCOMMAND_FUNC(hair_color); //** by fritz
-ATCOMMAND_FUNC(stat_all); //** by fritz
-ATCOMMAND_FUNC(char_change_sex); // by Yor
-ATCOMMAND_FUNC(char_block); // by Yor
-ATCOMMAND_FUNC(char_ban); // by Yor
-ATCOMMAND_FUNC(char_unblock); // by Yor
-ATCOMMAND_FUNC(char_unban); // by Yor
-ATCOMMAND_FUNC(mount_peco); // by Valaris
-ATCOMMAND_FUNC(char_mount_peco); // by Yor
-ATCOMMAND_FUNC(guildspy); // [Syrus22]
-ATCOMMAND_FUNC(partyspy); // [Syrus22]
-ATCOMMAND_FUNC(repairall); // [Valaris]
-ATCOMMAND_FUNC(guildrecall); // by Yor
-ATCOMMAND_FUNC(partyrecall); // by Yor
-//ATCOMMAND_FUNC(nuke); // [Valaris]
-ATCOMMAND_FUNC(enablenpc);
-ATCOMMAND_FUNC(disablenpc);
-ATCOMMAND_FUNC(servertime); // by Yor
-ATCOMMAND_FUNC(chardelitem); // by Yor
-ATCOMMAND_FUNC(jail); // by Yor
-ATCOMMAND_FUNC(unjail); // by Yor
-ATCOMMAND_FUNC(disguise); // [Valaris]
-ATCOMMAND_FUNC(undisguise); // by Yor
-ATCOMMAND_FUNC(chardisguise); // Kalaspuff
-ATCOMMAND_FUNC(charundisguise); // Kalaspuff
-ATCOMMAND_FUNC(email); // by Yor
-ATCOMMAND_FUNC(effect);//by Apple
-ATCOMMAND_FUNC(character_item_list); // by Yor
-ATCOMMAND_FUNC(character_storage_list); // by Yor
-ATCOMMAND_FUNC(character_cart_list); // by Yor
-ATCOMMAND_FUNC(addwarp); // by MouseJstr
-ATCOMMAND_FUNC(follow); // by MouseJstr
-ATCOMMAND_FUNC(skillon); // by MouseJstr
-ATCOMMAND_FUNC(skilloff); // by MouseJstr
-ATCOMMAND_FUNC(killer); // by MouseJstr
-ATCOMMAND_FUNC(npcmove); // by MouseJstr
-ATCOMMAND_FUNC(killable); // by MouseJstr
-ATCOMMAND_FUNC(charkillable); // by MouseJstr
-ATCOMMAND_FUNC(chareffect); // by MouseJstr
-ATCOMMAND_FUNC(chardye); // by MouseJstr
-ATCOMMAND_FUNC(charhairstyle); // by MouseJstr
-ATCOMMAND_FUNC(charhaircolor); // by MouseJstr
-ATCOMMAND_FUNC(dropall); // by MouseJstr
-ATCOMMAND_FUNC(chardropall); // by MouseJstr
-ATCOMMAND_FUNC(storeall); // by MouseJstr
-ATCOMMAND_FUNC(charstoreall); // by MouseJstr
-ATCOMMAND_FUNC(skillid); // by MouseJstr
-ATCOMMAND_FUNC(useskill); // by MouseJstr
-ATCOMMAND_FUNC(summon);
-ATCOMMAND_FUNC(rain);
-ATCOMMAND_FUNC(snow);
-ATCOMMAND_FUNC(sakura);
-ATCOMMAND_FUNC(fog);
-ATCOMMAND_FUNC(leaves);
-ATCOMMAND_FUNC(adjgmlvl); // by MouseJstr
-ATCOMMAND_FUNC(adjcmdlvl); // by MouseJstr
-ATCOMMAND_FUNC(trade); // by MouseJstr
-ATCOMMAND_FUNC(send); // by davidsiaw
-ATCOMMAND_FUNC(setbattleflag); // by MouseJstr
-ATCOMMAND_FUNC(unmute); // [Valaris]
-ATCOMMAND_FUNC(uptime); // by MC Cameri
-ATCOMMAND_FUNC(changesex); // by MC Cameri
-ATCOMMAND_FUNC(mute); // celest
-ATCOMMAND_FUNC(refresh); // by MC Cameri
-ATCOMMAND_FUNC(petid); // by MC Cameri
-ATCOMMAND_FUNC(identify); // by MC Cameri
-ATCOMMAND_FUNC(gmotd); // Added by MC Cameri, created by davidsiaw
-ATCOMMAND_FUNC(misceffect); // by MC Cameri
+#define MAX_MSG 1000
+char *msg_table[MAX_MSG]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others)
+
+#define ACMD_FUNC(x) int atcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message)
+ACMD_FUNC(broadcast);
+ACMD_FUNC(localbroadcast);
+ACMD_FUNC(rura);
+ACMD_FUNC(where);
+ACMD_FUNC(jumpto);
+ACMD_FUNC(jump);
+ACMD_FUNC(who);
+ACMD_FUNC(who2);
+ACMD_FUNC(who3);
+ACMD_FUNC(whomap);
+ACMD_FUNC(whomap2);
+ACMD_FUNC(whomap3);
+ACMD_FUNC(whogm); // by Yor
+ACMD_FUNC(whozeny); // [Valaris]
+ACMD_FUNC(happyhappyjoyjoy); // [Valaris]
+ACMD_FUNC(save);
+ACMD_FUNC(load);
+ACMD_FUNC(speed);
+ACMD_FUNC(storage);
+ACMD_FUNC(guildstorage);
+ACMD_FUNC(option);
+ACMD_FUNC(hide);
+ACMD_FUNC(jobchange);
+ACMD_FUNC(die);
+ACMD_FUNC(kill);
+ACMD_FUNC(alive);
+ACMD_FUNC(kami);
+ACMD_FUNC(heal);
+ACMD_FUNC(item);
+ACMD_FUNC(item2);
+ACMD_FUNC(itemreset);
+ACMD_FUNC(itemcheck);
+ACMD_FUNC(baselevelup);
+ACMD_FUNC(joblevelup);
+ACMD_FUNC(help);
+ACMD_FUNC(gm);
+ACMD_FUNC(pvpoff);
+ACMD_FUNC(pvpon);
+ACMD_FUNC(gvgoff);
+ACMD_FUNC(gvgon);
+ACMD_FUNC(model);
+ACMD_FUNC(go);
+ACMD_FUNC(monster);
+ACMD_FUNC(monstersmall);
+ACMD_FUNC(monsterbig);
+ACMD_FUNC(spawn);
+ACMD_FUNC(killmonster);
+ACMD_FUNC(killmonster2);
+ACMD_FUNC(refine);
+ACMD_FUNC(produce);
+ACMD_FUNC(memo);
+ACMD_FUNC(gat);
+ACMD_FUNC(packet);
+ACMD_FUNC(statuspoint);
+ACMD_FUNC(skillpoint);
+ACMD_FUNC(zeny);
+ACMD_FUNC(param);
+ACMD_FUNC(guildlevelup);
+ACMD_FUNC(makeegg);
+ACMD_FUNC(hatch);
+ACMD_FUNC(petfriendly);
+ACMD_FUNC(pethungry);
+ACMD_FUNC(petrename);
+ACMD_FUNC(recall);
+ACMD_FUNC(recallall);
+ACMD_FUNC(revive);
+ACMD_FUNC(character_stats_all);
+ACMD_FUNC(character_save);
+ACMD_FUNC(night);
+ACMD_FUNC(day);
+ACMD_FUNC(doom);
+ACMD_FUNC(doommap);
+ACMD_FUNC(raise);
+ACMD_FUNC(raisemap);
+ACMD_FUNC(character_baselevel);
+ACMD_FUNC(character_joblevel);
+ACMD_FUNC(kick);
+ACMD_FUNC(kickall);
+ACMD_FUNC(allskill);
+ACMD_FUNC(questskill);
+ACMD_FUNC(charquestskill);
+ACMD_FUNC(lostskill);
+ACMD_FUNC(charlostskill);
+ACMD_FUNC(spiritball);
+ACMD_FUNC(party);
+ACMD_FUNC(guild);
+ACMD_FUNC(charskreset);
+ACMD_FUNC(charstreset);
+ACMD_FUNC(charreset);
+ACMD_FUNC(charstpoint);
+ACMD_FUNC(charmodel);
+ACMD_FUNC(charskpoint);
+ACMD_FUNC(agitstart);
+ACMD_FUNC(agitend);
+ACMD_FUNC(reloaditemdb);
+ACMD_FUNC(reloadmobdb);
+ACMD_FUNC(reloadskilldb);
+ACMD_FUNC(reloadscript);
+ACMD_FUNC(reloadgmdb); // by Yor
+ACMD_FUNC(reloadatcommand);
+ACMD_FUNC(reloadbattleconf);
+ACMD_FUNC(reloadstatusdb);
+ACMD_FUNC(reloadpcdb);
+ACMD_FUNC(mapexit);
+ACMD_FUNC(idsearch);
+ACMD_FUNC(mapinfo);
+ACMD_FUNC(dye); //** by fritz
+ACMD_FUNC(hair_style); //** by fritz
+ACMD_FUNC(hair_color); //** by fritz
+ACMD_FUNC(stat_all); //** by fritz
+ACMD_FUNC(char_change_sex); // by Yor
+ACMD_FUNC(char_block); // by Yor
+ACMD_FUNC(char_ban); // by Yor
+ACMD_FUNC(char_unblock); // by Yor
+ACMD_FUNC(char_unban); // by Yor
+ACMD_FUNC(mount_peco); // by Valaris
+ACMD_FUNC(char_mount_peco); // by Yor
+ACMD_FUNC(guildspy); // [Syrus22]
+ACMD_FUNC(partyspy); // [Syrus22]
+ACMD_FUNC(repairall); // [Valaris]
+ACMD_FUNC(guildrecall); // by Yor
+ACMD_FUNC(partyrecall); // by Yor
+ACMD_FUNC(nuke); // [Valaris]
+ACMD_FUNC(enablenpc);
+ACMD_FUNC(hidenpc);
+ACMD_FUNC(disablenpc);
+ACMD_FUNC(servertime); // by Yor
+ACMD_FUNC(chardelitem); // by Yor
+ACMD_FUNC(jail); // by Yor
+ACMD_FUNC(unjail); // by Yor
+ACMD_FUNC(disguise); // [Valaris]
+ACMD_FUNC(undisguise); // by Yor
+ACMD_FUNC(chardisguise); // Kalaspuff
+ACMD_FUNC(charundisguise); // Kalaspuff
+ACMD_FUNC(email); // by Yor
+ACMD_FUNC(effect);//by Apple
+ACMD_FUNC(character_cart_list); // by Yor
+ACMD_FUNC(addwarp); // by MouseJstr
+ACMD_FUNC(follow); // by MouseJstr
+ACMD_FUNC(skillon); // by MouseJstr
+ACMD_FUNC(skilloff); // by MouseJstr
+ACMD_FUNC(killer); // by MouseJstr
+ACMD_FUNC(npcmove); // by MouseJstr
+ACMD_FUNC(killable); // by MouseJstr
+ACMD_FUNC(charkillable); // by MouseJstr
+ACMD_FUNC(dropall); // by MouseJstr
+ACMD_FUNC(chardropall); // by MouseJstr
+ACMD_FUNC(storeall); // by MouseJstr
+ACMD_FUNC(charstoreall); // by MouseJstr
+ACMD_FUNC(skillid); // by MouseJstr
+ACMD_FUNC(useskill); // by MouseJstr
+ACMD_FUNC(summon);
+ACMD_FUNC(rain);
+ACMD_FUNC(snow);
+ACMD_FUNC(sakura);
+ACMD_FUNC(fog);
+ACMD_FUNC(leaves);
+ACMD_FUNC(adjgmlvl); // by MouseJstr
+ACMD_FUNC(adjcmdlvl); // by MouseJstr
+ACMD_FUNC(trade); // by MouseJstr
+ACMD_FUNC(send); // by davidsiaw
+ACMD_FUNC(setbattleflag); // by MouseJstr
+ACMD_FUNC(unmute); // [Valaris]
+ACMD_FUNC(clearweather); // Dexity
+ACMD_FUNC(uptime); // by MC Cameri
+ACMD_FUNC(changesex); // by MC Cameri
+ACMD_FUNC(mute); // celest
+ACMD_FUNC(refresh); // by MC Cameri
+ACMD_FUNC(petid); // by MC Cameri
+ACMD_FUNC(identify); // by MC Cameri
+ACMD_FUNC(gmotd); // Added by MC Cameri, created by davidsiaw
+ACMD_FUNC(misceffect); // by MC Cameri
+ACMD_FUNC(mobsearch);
+ACMD_FUNC(cleanmap);
+ACMD_FUNC(npctalk);
+ACMD_FUNC(pettalk);
+ACMD_FUNC(users);
+ACMD_FUNC(autoloot); // by Upa-Kun
#ifndef TXT_ONLY
-ATCOMMAND_FUNC(checkmail); // [Valaris]
-ATCOMMAND_FUNC(listmail); // [Valaris]
-ATCOMMAND_FUNC(listnewmail); // [Valaris]
-ATCOMMAND_FUNC(readmail); // [Valaris]
-ATCOMMAND_FUNC(sendmail); // [Valaris]
-ATCOMMAND_FUNC(sendprioritymail); // [Valaris]
-ATCOMMAND_FUNC(deletemail); // [Valaris]
-ATCOMMAND_FUNC(sound); // [Valaris]
-ATCOMMAND_FUNC(refreshonline); // [Valaris]
+ACMD_FUNC(checkmail); // [Valaris]
+ACMD_FUNC(listmail); // [Valaris]
+ACMD_FUNC(listnewmail); // [Valaris]
+ACMD_FUNC(readmail); // [Valaris]
+ACMD_FUNC(sendmail); // [Valaris]
+ACMD_FUNC(sendprioritymail); // [Valaris]
+ACMD_FUNC(deletemail); // [Valaris]
+//ACMD_FUNC(sound); // [Valaris]
+ACMD_FUNC(refreshonline); // [Valaris]
#endif /* TXT_ONLY */
-ATCOMMAND_FUNC(skilltree); // by MouseJstr
+ACMD_FUNC(skilltree); // by MouseJstr
+
+ACMD_FUNC(marry); // by MouseJstr
+ACMD_FUNC(divorce); // by MouseJstr
+ACMD_FUNC(rings); // by MouseJstr
+
+ACMD_FUNC(grind); // by MouseJstr
+ACMD_FUNC(grind2); // by MouseJstr
+
+#ifdef DMALLOC
+ACMD_FUNC(dmstart); // by MouseJstr
+ACMD_FUNC(dmtick); // by MouseJstr
+#endif
+
+ACMD_FUNC(jumptoid); // by Dino9021
+ACMD_FUNC(jumptoid2); // by Dino9021
+ACMD_FUNC(recallid); // by Dino9021
+ACMD_FUNC(recallid2); // by Dino9021
+ACMD_FUNC(kickid); // by Dino9021
+ACMD_FUNC(kickid2); // by Dino9021
+ACMD_FUNC(reviveid); // by Dino9021
+ACMD_FUNC(reviveid2); // by Dino9021
+ACMD_FUNC(killid); // by Dino9021
+ACMD_FUNC(killid2); // by Dino9021
+ACMD_FUNC(charkillableid); // by Dino9021
+ACMD_FUNC(charkillableid2); // by Dino9021
+ACMD_FUNC(sound);
+ACMD_FUNC(undisguiseall);
+ACMD_FUNC(disguiseall);
+ACMD_FUNC(changelook);
+ACMD_FUNC(mobinfo); //by Lupus
+ACMD_FUNC(adopt); // by Veider
/*==========================================
*AtCommandInfo atcommand_info[]\‘¢‘̂̒è‹`
@@ -240,8 +275,6 @@ ATCOMMAND_FUNC(skilltree); // by MouseJstr
// First char of commands is configured in atcommand_athena.conf. Leave @ in this list for default value.
// to set default level, read atcommand_athena.conf first please.
static AtCommandInfo atcommand_info[] = {
- { AtCommand_RuraP, "@rura+", 60, atcommand_rurap },
- { AtCommand_RuraP, "@charwarp", 60, atcommand_rurap },
{ AtCommand_Rura, "@rura", 40, atcommand_rura },
{ AtCommand_Warp, "@warp", 40, atcommand_rura },
{ AtCommand_Where, "@where", 1, atcommand_where },
@@ -359,16 +392,15 @@ static AtCommandInfo atcommand_info[] = {
{ AtCommand_ReloadItemDB, "@reloaditemdb", 99, atcommand_reloaditemdb }, // admin command
{ AtCommand_ReloadMobDB, "@reloadmobdb", 99, atcommand_reloadmobdb }, // admin command
{ AtCommand_ReloadSkillDB, "@reloadskilldb", 99, atcommand_reloadskilldb }, // admin command
-#ifndef TXT_ONLY
- { AtCommand_Rehash, "@rehash", 99, atcommand_rehash }, // admin command
-#else /* TXT_ONLY */
{ AtCommand_ReloadScript, "@reloadscript", 99, atcommand_reloadscript }, // admin command
-#endif /* TXT_ONLY */
{ AtCommand_ReloadGMDB, "@reloadgmdb", 99, atcommand_reloadgmdb }, // admin command
+ { AtCommand_ReloadAtcommand, "@reloadatcommand", 99, atcommand_reloadatcommand },
+ { AtCommand_ReloadBattleConf, "@reloadbattleconf",99, atcommand_reloadbattleconf },
+ { AtCommand_ReloadStatusDB, "@reloadstatusdb", 99, atcommand_reloadstatusdb },
+ { AtCommand_ReloadPcDB, "@reloadpcdb", 99, atcommand_reloadpcdb },
{ AtCommand_CharModel, "@charmodel", 50, atcommand_charmodel },
{ AtCommand_CharSKPoint, "@charskpoint", 60, atcommand_charskpoint },
{ AtCommand_CharSTPoint, "@charstpoint", 60, atcommand_charstpoint },
- { AtCommand_CharZeny, "@charzeny", 60, atcommand_charzeny },
{ AtCommand_MapInfo, "@mapinfo", 99, atcommand_mapinfo },
{ AtCommand_Dye, "@dye", 40, atcommand_dye }, // by fritz
{ AtCommand_Dye, "@ccolor", 40, atcommand_dye }, // by fritz
@@ -380,7 +412,7 @@ static AtCommandInfo atcommand_info[] = {
{ AtCommand_StatAll, "@statsall", 60, atcommand_stat_all },
{ AtCommand_StatAll, "@allstats", 60, atcommand_stat_all }, // by fritz
{ AtCommand_StatAll, "@allstat", 60, atcommand_stat_all }, // by fritz
- { AtCommand_CharChangeSex, "@charchangesex", 60, atcommand_char_change_sex }, // by Yor
+// { AtCommand_CharChangeSex, "@charchangesex", 60, atcommand_char_change_sex }, // by Yor
{ AtCommand_CharBlock, "@block", 60, atcommand_char_block }, // by Yor
{ AtCommand_CharBlock, "@charblock", 60, atcommand_char_block }, // by Yor
{ AtCommand_CharBan, "@ban", 60, atcommand_char_ban }, // by Yor
@@ -400,8 +432,9 @@ static AtCommandInfo atcommand_info[] = {
{ AtCommand_RepairAll, "@repairall", 60, atcommand_repairall }, // [Valaris]
{ AtCommand_GuildRecall, "@guildrecall", 60, atcommand_guildrecall }, // by Yor
{ AtCommand_PartyRecall, "@partyrecall", 60, atcommand_partyrecall }, // by Yor
-// { AtCommand_Nuke, "@nuke", 60, atcommand_nuke }, // [Valaris]
+ { AtCommand_Nuke, "@nuke", 60, atcommand_nuke }, // [Valaris]
{ AtCommand_Enablenpc, "@enablenpc", 80, atcommand_enablenpc }, // []
+ { AtCommand_Hidenpc, "@hidenpc", 80, atcommand_hidenpc }, // []
{ AtCommand_Disablenpc, "@disablenpc", 80, atcommand_disablenpc }, // []
{ AtCommand_ServerTime, "@time", 0, atcommand_servertime }, // by Yor
{ AtCommand_ServerTime, "@date", 0, atcommand_servertime }, // by Yor
@@ -419,8 +452,8 @@ static AtCommandInfo atcommand_info[] = {
{ AtCommand_CharUnDisguise, "@charundisguise", 60, atcommand_charundisguise }, // Kalaspuff
{ AtCommand_EMail, "@email", 0, atcommand_email }, // by Yor
{ AtCommand_Effect, "@effect", 40, atcommand_effect }, // by Apple
- { AtCommand_Char_Item_List, "@charitemlist", 40, atcommand_character_item_list }, // by Yor
- { AtCommand_Char_Storage_List, "@charstoragelist", 40, atcommand_character_storage_list }, // by Yor
+// { AtCommand_Char_Item_List, "@charitemlist", 40, atcommand_character_item_list }, // by Yor, now #itemlist
+// { AtCommand_Char_Storage_List, "@charstoragelist", 40, atcommand_character_storage_list }, // by Yor, now #storagelist
{ AtCommand_Char_Cart_List, "@charcartlist", 40, atcommand_character_cart_list }, // by Yor
{ AtCommand_Follow, "@follow", 10, atcommand_follow }, // by MouseJstr
{ AtCommand_AddWarp, "@addwarp", 20, atcommand_addwarp }, // by MouseJstr
@@ -430,12 +463,6 @@ static AtCommandInfo atcommand_info[] = {
{ AtCommand_NpcMove, "@npcmove", 20, atcommand_npcmove }, // by MouseJstr
{ AtCommand_Killable, "@killable", 40, atcommand_killable }, // by MouseJstr
{ AtCommand_CharKillable, "@charkillable", 40, atcommand_charkillable }, // by MouseJstr
- { AtCommand_Chareffect, "@chareffect", 40, atcommand_chareffect }, // MouseJstr
-/*
- { AtCommand_Chardye, "@chardye", 40, atcommand_chardye }, // MouseJstr
- { AtCommand_Charhairstyle, "@charhairstyle", 40, atcommand_charhairstyle }, // MouseJstr
- { AtCommand_Charhaircolor, "@charhaircolor", 40, atcommand_charhaircolor }, // MouseJstr
-*/
{ AtCommand_Dropall, "@dropall", 40, atcommand_dropall }, // MouseJstr
{ AtCommand_Chardropall, "@chardropall", 40, atcommand_chardropall }, // MouseJstr
{ AtCommand_Storeall, "@storeall", 40, atcommand_storeall }, // MouseJstr
@@ -459,8 +486,9 @@ static AtCommandInfo atcommand_info[] = {
{ AtCommand_Send, "@send", 60, atcommand_send },
{ AtCommand_SetBattleFlag, "@setbattleflag", 60, atcommand_setbattleflag },
{ AtCommand_UnMute, "@unmute", 60, atcommand_unmute }, // [Valaris]
+ { AtCommand_Clearweather, "@clearweather", 99, atcommand_clearweather }, // Dexity
{ AtCommand_UpTime, "@uptime", 0, atcommand_uptime }, // by MC Cameri
- { AtCommand_ChangeSex, "@changesex", 1, atcommand_changesex }, // by MC Cameri
+// { AtCommand_ChangeSex, "@changesex", 1, atcommand_changesex }, // by MC Cameri
{ AtCommand_Mute, "@mute", 99, atcommand_mute }, // [celest]
{ AtCommand_Mute, "@red", 99, atcommand_mute }, // [celest]
{ AtCommand_WhoZeny, "@whozeny", 20, atcommand_whozeny }, // [Valaris]
@@ -470,6 +498,12 @@ static AtCommandInfo atcommand_info[] = {
{ AtCommand_Identify, "@identify", 40, atcommand_identify }, // by MC Cameri
{ AtCommand_Gmotd, "@gmotd", 0, atcommand_gmotd }, // Added by MC Cameri, created by davidsiaw
{ AtCommand_MiscEffect, "@misceffect", 50, atcommand_misceffect }, // by MC Cameri
+ { AtCommand_MobSearch, "@mobsearch", 0, atcommand_mobsearch },
+ { AtCommand_CleanMap, "@cleanmap", 0, atcommand_cleanmap },
+ { AtCommand_NpcTalk, "@npctalk", 0, atcommand_npctalk },
+ { AtCommand_PetTalk, "@pettalk", 0, atcommand_pettalk },
+ { AtCommand_Users, "@users", 0, atcommand_users },
+ { AtCommand_ResetState, "/reset", 40, NULL },
#ifndef TXT_ONLY // sql-only commands
{ AtCommand_CheckMail, "@checkmail", 1, atcommand_listmail }, // [Valaris]
@@ -483,17 +517,60 @@ static AtCommandInfo atcommand_info[] = {
#endif /* TXT_ONLY */
{ AtCommand_SkillTree, "@skilltree", 40, atcommand_skilltree }, // [MouseJstr]
+ { AtCommand_Marry, "@marry", 40, atcommand_marry }, // [MouseJstr]
+ { AtCommand_Divorce, "@divorce", 40, atcommand_divorce }, // [MouseJstr]
+ { AtCommand_Rings, "@rings", 40, atcommand_rings }, // [MouseJstr]
+ { AtCommand_Grind, "@grind", 99, atcommand_grind }, // [MouseJstr]
+ { AtCommand_Grind2, "@grind2", 99, atcommand_grind2 }, // [MouseJstr]
+
+#ifdef DMALLOC
+ { AtCommand_DMStart, "@dmstart", 99, atcommand_dmstart }, // [MouseJstr]
+ { AtCommand_DMTick, "@dmtick", 99, atcommand_dmtick }, // [MouseJstr]
+#endif
+ { AtCommand_JumpToId, "@jumptoid", 20, atcommand_jumptoid }, // [Dino9021]
+ { AtCommand_JumpToId, "@warptoid", 20, atcommand_jumptoid }, // [Dino9021]
+ { AtCommand_JumpToId, "@gotoid", 20, atcommand_jumptoid }, // [Dino9021]
+ { AtCommand_JumpToId2, "@jumptoid2", 20, atcommand_jumptoid2 }, // [Dino9021]
+ { AtCommand_JumpToId2, "@warptoid2", 20, atcommand_jumptoid2 }, // [Dino9021]
+ { AtCommand_JumpToId2, "@gotoid2", 20, atcommand_jumptoid2 }, // [Dino9021]
+ { AtCommand_RecallId, "@recallid", 60, atcommand_recallid }, // [Dino9021]
+ { AtCommand_RecallId2, "@recallid2", 60, atcommand_recallid2 }, // [Dino9021]
+ { AtCommand_KickId, "@kickid", 99, atcommand_kickid }, // [Dino9021]
+ { AtCommand_KickId2, "@kickid2", 99, atcommand_kickid2 }, // [Dino9021]
+ { AtCommand_ReviveId, "@reviveid", 60, atcommand_reviveid }, // [Dino9021]
+ { AtCommand_ReviveId2, "@reviveid2", 60, atcommand_reviveid2 }, // [Dino9021]
+ { AtCommand_KillId, "@killid", 60, atcommand_killid }, // [Dino9021]
+ { AtCommand_KillId2, "@killid2", 60, atcommand_killid2 }, // [Dino9021]
+ { AtCommand_CharKillableId, "@charkillableid", 40, atcommand_charkillableid }, // [Dino9021]
+ { AtCommand_CharKillableId2, "@charkillableid2", 40, atcommand_charkillableid2 }, // [Dino9021]
+ { AtCommand_Sound, "@sound", 40, atcommand_sound },
+ { AtCommand_UndisguiseAll, "@undisguiseall", 99, atcommand_undisguiseall },
+ { AtCommand_DisguiseAll, "@disguiseall", 99, atcommand_disguiseall },
+ { AtCommand_ChangeLook, "@changelook", 99, atcommand_changelook },
+ { AtCommand_AutoLoot, "@autoloot", 10, atcommand_autoloot }, // Upa-Kun
+ { AtCommand_MobInfo, "@mobinfo", 1, atcommand_mobinfo }, // [Lupus]
+ { AtCommand_MobInfo, "@monsterinfo", 1, atcommand_mobinfo }, // [Lupus]
+ { AtCommand_MobInfo, "@mi", 1, atcommand_mobinfo }, // [Lupus]
+ { AtCommand_Adopt, "@adopt", 40, atcommand_adopt }, // [Veider]
+
// add new commands before this line
{ AtCommand_Unknown, NULL, 1, NULL }
};
+/*=========================================
+ * Generic variables
+ *-----------------------------------------
+ */
+char atcmd_output[200];
+char atcmd_player_name[100];
+
/*====================================================
* This function return the name of the job (by [Yor])
*----------------------------------------------------
*/
-char * job_name(int class) {
- switch (class) {
+char * job_name(int class_) {
+ switch (class_) {
case 0: return "Novice";
case 1: return "Swordsman";
case 2: return "Mage";
@@ -597,7 +674,7 @@ int lowtohigh_compare (const void * a, const void * b)
// Return the message string of the specified number by [Yor]
//-----------------------------------------------------------
char * msg_txt(int msg_number) {
- if (msg_number >= 0 && msg_number < (int)(sizeof(msg_table) / sizeof(msg_table[0])) &&
+ if (msg_number >= 0 && msg_number < MAX_MSG &&
msg_table[msg_number] != NULL && msg_table[msg_number][0] != '\0')
return msg_table[msg_number];
@@ -607,9 +684,9 @@ char * msg_txt(int msg_number) {
//------------------------------------------------------------
// E-mail check: return 0 (not correct) or 1 (valid). by [Yor]
//------------------------------------------------------------
-int e_mail_check(unsigned char *email) {
+int e_mail_check(char *email) {
char ch;
- unsigned char* last_arobas;
+ char* last_arobas;
// athena limits
if (strlen(email) < 3 || strlen(email) > 39)
@@ -670,6 +747,11 @@ is_atcommand(const int fd, struct map_session_data* sd, const char* message, int
nullpo_retr(AtCommand_None, sd);
+ if (!battle_config.allow_atcommand_when_mute &&
+ sd->sc_count && sd->sc_data[SC_NOCHAT].timer != -1) {
+ return AtCommand_Unknown;
+ }
+
if (!message || !*message)
return AtCommand_None;
@@ -683,13 +765,12 @@ is_atcommand(const int fd, struct map_session_data* sd, const char* message, int
if (!*str)
return AtCommand_None;
- type = atcommand(gmlvl > 0 ? gmlvl : pc_isGM(sd), str, &info);
+ type = atcommand(sd, gmlvl > 0 ? gmlvl : pc_isGM(sd), str, &info);
if (type != AtCommand_None) {
char command[100];
- char output[200];
const char* p = str;
memset(command, '\0', sizeof(command));
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
while (*p && !isspace(*p))
p++;
if (p - str >= sizeof(command)) // too long
@@ -699,20 +780,16 @@ is_atcommand(const int fd, struct map_session_data* sd, const char* message, int
p++;
if (type == AtCommand_Unknown || info.proc == NULL) {
- sprintf(output, msg_table[153], command); // %s is Unknown Command.
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[153], command); // %s is Unknown Command.
+ clif_displaymessage(fd, atcmd_output);
} else {
if (info.proc(fd, sd, command, p) != 0) {
// Command can not be executed
- sprintf(output, msg_table[154], command); // %s failed.
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[154], command); // %s failed.
+ clif_displaymessage(fd, atcmd_output);
}
}
- // ToDo: Fix Logs :)
- //if((log_config.gm) && (info.level >= log_config.gm))
- // log_atcommand(sd, message);
-
return info.type;
}
@@ -723,7 +800,7 @@ is_atcommand(const int fd, struct map_session_data* sd, const char* message, int
*
*------------------------------------------
*/
-AtCommandType atcommand(const int level, const char* message, struct AtCommandInfo* info) {
+AtCommandType atcommand(struct map_session_data* sd, const int level, const char* message, struct AtCommandInfo* info) {
char* p = (char *)message; // it's 'char' and not 'const char' to have possibility to modify the first character if necessary
if (!info)
@@ -756,6 +833,8 @@ AtCommandType atcommand(const int level, const char* message, struct AtCommandIn
return AtCommand_None;
else
return AtCommand_Unknown;
+ } else if((log_config.gm) && (atcommand_info[i].level >= log_config.gm)) {
+ log_atcommand(sd, message);
}
memcpy(info, &atcommand_info[i], sizeof atcommand_info[i]);
} else {
@@ -770,49 +849,73 @@ AtCommandType atcommand(const int level, const char* message, struct AtCommandIn
*------------------------------------------
*/
static int atkillmonster_sub(struct block_list *bl, va_list ap) {
- int flag = va_arg(ap, int);
-
- nullpo_retr(0, bl);
+ struct mob_data *md;
+ int flag;
+
+ nullpo_retr(0, ap);
+ nullpo_retr(0, md=(struct mob_data *)bl);
+ flag = va_arg(ap, int);
if (flag)
- mob_damage(NULL, (struct mob_data *)bl, ((struct mob_data *)bl)->hp, 2);
+ mob_damage(NULL, md, md->hp, 2);
else
- mob_delete((struct mob_data *)bl);
-
+ mob_delete(md);
+
return 0;
}
-
-#ifndef TXT_ONLY
-static int atkillnpc_sub(struct block_list *bl, va_list ap)
+/*==========================================
+ * Mob search
+ *------------------------------------------
+ */
+static int atmobsearch_sub(struct block_list *bl,va_list ap)
{
- int flag = va_arg(ap,int);
+ int mob_id,fd;
+ static int number=0;
+ struct mob_data *md;
- nullpo_retr(0, bl);
+ nullpo_retr(0, bl);
- npc_delete((struct npc_data *)bl);
+ if(!ap){
+ number=0;
+ return 0;
+ }
+ mob_id = va_arg(ap,int);
+ fd = va_arg(ap,int);
- flag = 0;
+ md = (struct mob_data *)bl;
- return 0;
+ if(md && fd && (mob_id==-1 || (md->class_==mob_id))){
+ snprintf(atcmd_output, sizeof atcmd_output, "%2d[%3d:%3d] %s",
+ ++number,bl->x, bl->y,md->name);
+ clif_displaymessage(fd, atcmd_output);
+ }
+ return 0;
}
-
-void rehash( const int fd, struct map_session_data* sd )
+/*==========================================
+ * cleanmap
+ *------------------------------------------
+ */
+static int atcommand_cleanmap_sub(struct block_list *bl,va_list ap)
{
- int map_id = 0;
+ struct flooritem_data *fitem;
- int LOADED_MAPS = map_num;
-
- for (map_id = 0; map_id < LOADED_MAPS;map_id++) {
+ nullpo_retr(0, bl);
- if (map_id > LOADED_MAPS)
- break;
+ fitem = (struct flooritem_data *)bl;
+ if(fitem==NULL || fitem->bl.type!=BL_ITEM){
+ if(battle_config.error_log)
+ printf("map_clearflooritem_timer : error\n");
+ return 1;
+ }
+ delete_timer(fitem->cleartimer,map_clearflooritem_timer);
+ if(fitem->item_data.card[0] == (short)0xff00)
+ intif_delete_petdata(*((long *)(&fitem->item_data.card[1])));
+ clif_clearflooritem(fitem,0);
+ map_delobject(fitem->bl.id);
- map_foreachinarea(atkillmonster_sub, map_id, 0, 0, map[map_id].xs, map[map_id].ys, BL_MOB, 0);
- map_foreachinarea(atkillnpc_sub, map_id, 0, 0, map[map_id].xs, map[map_id].ys, BL_NPC, 0);
- }
+ return 0;
}
-#endif /* not TXT_ONLY */
/*==========================================
* Read Message Data
*------------------------------------------
@@ -821,12 +924,15 @@ int msg_config_read(const char *cfgName) {
int msg_number;
char line[1024], w1[1024], w2[1024];
FILE *fp;
+ static int called = 1;
if ((fp = fopen(cfgName, "r")) == NULL) {
printf("Messages file not found: %s\n", cfgName);
return 1;
}
+ if ((--called) == 0)
+ memset(&msg_table[0], 0, sizeof(msg_table[0]) * MAX_MSG);
while(fgets(line, sizeof(line)-1, fp)) {
if (line[0] == '/' && line[1] == '/')
continue;
@@ -835,9 +941,13 @@ int msg_config_read(const char *cfgName) {
msg_config_read(w2);
} else {
msg_number = atoi(w1);
- if (msg_number >= 0 && msg_number < (int)(sizeof(msg_table) / sizeof(msg_table[0])))
- strcpy(msg_table[msg_number], w2);
+ if (msg_number >= 0 && msg_number < MAX_MSG) {
+ if (msg_table[msg_number] != NULL)
+ aFree(msg_table[msg_number]);
+ msg_table[msg_number] = (char *)aCalloc(strlen(w2) + 1, sizeof (char));
+ strcpy(msg_table[msg_number],w2);
// printf("message #%d: '%s'.\n", msg_number, msg_table[msg_number]);
+ }
}
}
}
@@ -847,6 +957,17 @@ int msg_config_read(const char *cfgName) {
}
/*==========================================
+ * Cleanup Message Data
+ *------------------------------------------
+ */
+void do_final_msg () {
+ int i;
+ for (i = 0; i < MAX_MSG; i++)
+ aFree(msg_table[i]);
+ return;
+}
+
+/*==========================================
*
*------------------------------------------
*/
@@ -932,73 +1053,7 @@ int atcommand_send(
case 4:
WBUFW(buf,0)=0x190;
}
-
-
- }
- return 0;
-}
-
-/*==========================================
- * @rura+
- *------------------------------------------
- */
-int atcommand_rurap(
- const int fd, struct map_session_data* sd,
- const char* command, const char* message)
-{
- char map_name[100];
- char character[100];
- int x = 0, y = 0;
- struct map_session_data *pl_sd;
- int m;
-
- memset(map_name, '\0', sizeof(map_name));
- memset(character, '\0', sizeof(character));
-
- if (!message || !*message || sscanf(message, "%99s %d %d %99[^\n]", map_name, &x, &y, character) < 4) {
- clif_displaymessage(fd, "Usage: @charwarp/@rura+ <mapname> <x> <y> <char name>");
- return -1;
- }
-
- if (x <= 0)
- x = rand() % 399 + 1;
- if (y <= 0)
- y = rand() % 399 + 1;
- if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat)
- strcat(map_name, ".gat");
-
- if ((pl_sd = map_nick2sd(character)) != NULL) {
- if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can rura+ only lower or same GM level
- if (x > 0 && x < 400 && y > 0 && y < 400) {
- m = map_mapname2mapid(map_name);
- if (m >= 0 && map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
- clif_displaymessage(fd, "You are not authorised to warp someone to this map.");
- return -1;
- }
- if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
- clif_displaymessage(fd, "You are not authorised to warp this player from its actual map.");
- return -1;
- }
- if (pc_setpos(pl_sd, map_name, x, y, 3) == 0) {
- clif_displaymessage(pl_sd->fd, msg_table[0]); // Warped.
- clif_displaymessage(fd, msg_table[15]); // Player warped (message sends to player too).
- } else {
- clif_displaymessage(fd, msg_table[1]); // Map not found.
- return -1;
- }
- } else {
- clif_displaymessage(fd, msg_table[2]); // Coordinates out of range.
- return -1;
- }
- } else {
- clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
- return -1;
- }
- } else {
- clif_displaymessage(fd, msg_table[3]); // Character not found.
- return -1;
}
-
return 0;
}
@@ -1015,6 +1070,8 @@ int atcommand_rura(
int x = 0, y = 0;
int m;
+ nullpo_retr(-1, sd);
+
memset(map_name, '\0', sizeof(map_name));
if (!message || !*message || sscanf(message, "%99s %d %d", map_name, &x, &y) < 1) {
@@ -1033,11 +1090,11 @@ int atcommand_rura(
if (x > 0 && x < 400 && y > 0 && y < 400) {
m = map_mapname2mapid(map_name);
if (m >= 0 && map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
- clif_displaymessage(fd, "You are not authorised to warp you to this map.");
+ clif_displaymessage(fd, msg_table[247]);
return -1;
}
if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
- clif_displaymessage(fd, "You are not authorised to warp you from your actual map.");
+ clif_displaymessage(fd, msg_table[248]);
return -1;
}
if (pc_setpos(sd, map_name, x, y, 3) == 0)
@@ -1062,30 +1119,28 @@ int atcommand_where(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
- char output[200];
struct map_session_data *pl_sd = NULL;
nullpo_retr(-1, sd);
if (!message || !*message)
return -1;
- memset(character, '\0', sizeof character);
- if (sscanf(message, "%99[^\n]", character) < 1)
+ memset(atcmd_player_name, '\0', sizeof atcmd_player_name);
+ if (sscanf(message, "%99[^\n]", atcmd_player_name) < 1)
return -1;
- if(strncmp(sd->status.name,character,24)==0)
+ if(strncmp(sd->status.name,atcmd_player_name,24)==0)
return -1;
- if ((pl_sd = map_nick2sd(character)) == NULL) {
- snprintf(output, sizeof output, "%s %d %d",
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) == NULL) {
+ snprintf(atcmd_output, sizeof atcmd_output, "%s %d %d",
sd->mapname, sd->bl.x, sd->bl.y);
- clif_displaymessage(fd, output);
+ clif_displaymessage(fd, atcmd_output);
return -1;
}
- snprintf(output, sizeof output, "%s %s %d %d",
- character, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y);
- clif_displaymessage(fd, output);
-
+ snprintf(atcmd_output, sizeof atcmd_output, "%s %s %d %d",
+ atcmd_player_name, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y);
+ clif_displaymessage(fd, atcmd_output);
+
return 0;
}
@@ -1097,35 +1152,33 @@ int atcommand_jumpto(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
- char output[200];
struct map_session_data *pl_sd = NULL;
nullpo_retr(-1, sd);
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
clif_displaymessage(fd, "Please, enter a player name (usage: @jumpto/@warpto/@goto <char name>).");
return -1;
}
-
- memset(character, '\0', sizeof character);
- if (sscanf(message, "%99[^\n]", character) < 1)
+
+ memset(atcmd_player_name, '\0', sizeof atcmd_player_name);
+ if (sscanf(message, "%99[^\n]", atcmd_player_name) < 1)
return -1;
- if(strncmp(sd->status.name,character,24)==0) //Yourself mate? Tsk tsk tsk.
+ if(strncmp(sd->status.name,atcmd_player_name,24)==0) //Yourself mate? Tsk tsk tsk.
return -1;
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
- clif_displaymessage(fd, "You are not authorised to warp you to the map of this player.");
+ clif_displaymessage(fd, msg_table[247]);
return -1;
}
if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
- clif_displaymessage(fd, "You are not authorised to warp you from your actual map.");
+ clif_displaymessage(fd, msg_table[248]);
return -1;
}
pc_setpos(sd, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y, 3);
- sprintf(output, msg_table[4], character); // Jump to %s
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[4], atcmd_player_name); // Jump to %s
+ clif_displaymessage(fd, atcmd_output);
} else {
clif_displaymessage(fd, msg_table[3]); // Character not found.
return -1;
@@ -1142,10 +1195,11 @@ int atcommand_jump(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char output[200];
int x = 0, y = 0;
- memset(output, '\0', sizeof(output));
+ nullpo_retr(-1, sd);
+
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
sscanf(message, "%d %d", &x, &y);
@@ -1154,17 +1208,13 @@ int atcommand_jump(
if (y <= 0)
y = rand() % 399 + 1;
if (x > 0 && x < 400 && y > 0 && y < 400) {
- if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
- clif_displaymessage(fd, "You are not authorised to warp you to your actual map.");
- return -1;
- }
- if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
- clif_displaymessage(fd, "You are not authorised to warp you from your actual map.");
+ if (sd->bl.m >= 0 && (map[sd->bl.m].flag.nowarp || map[sd->bl.m].flag.nowarpto) && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
+ clif_displaymessage(fd, msg_table[248]);
return -1;
}
pc_setpos(sd, sd->mapname, x, y, 3);
- sprintf(output, msg_table[5], x, y); // Jump to %d %d
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[5], x, y); // Jump to %d %d
+ clif_displaymessage(fd, atcmd_output);
} else {
clif_displaymessage(fd, msg_table[2]); // Coordinates out of range.
return -1;
@@ -1181,14 +1231,15 @@ int atcommand_who(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char output[200];
struct map_session_data *pl_sd;
int i, j, count;
int pl_GM_level, GM_level;
char match_text[100];
char player_name[24];
- memset(output, '\0', sizeof(output));
+ nullpo_retr(-1, sd);
+
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
memset(match_text, '\0', sizeof(match_text));
memset(player_name, '\0', sizeof(player_name));
@@ -1200,7 +1251,7 @@ int atcommand_who(
count = 0;
GM_level = pc_isGM(sd);
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) {
pl_GM_level = pc_isGM(pl_sd);
if (!((battle_config.hide_GM_session || (pl_sd->status.option & OPTION_HIDE)) && (pl_GM_level > GM_level))) { // you can look only lower or same level
memcpy(player_name, pl_sd->status.name, 24);
@@ -1208,10 +1259,10 @@ int atcommand_who(
player_name[j] = tolower(player_name[j]);
if (strstr(player_name, match_text) != NULL) { // search with no case sensitive
if (pl_GM_level > 0)
- sprintf(output, "Name: %s (GM:%d) | Location: %s %d %d", pl_sd->status.name, pl_GM_level, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y);
+ sprintf(atcmd_output, "(CID:%d/AID:%d) Name: %s (GM:%d) | Location: %s %d %d", pl_sd->status.char_id, pl_sd->status.account_id, pl_sd->status.name, pl_GM_level, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y);
else
- sprintf(output, "Name: %s | Location: %s %d %d", pl_sd->status.name, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "(CID:%d/AID:%d) Name: %s | Location: %s %d %d", pl_sd->status.char_id, pl_sd->status.account_id, pl_sd->status.name, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y);
+ clif_displaymessage(fd, atcmd_output);
count++;
}
}
@@ -1223,8 +1274,8 @@ int atcommand_who(
else if (count == 1)
clif_displaymessage(fd, msg_table[29]); // 1 player found.
else {
- sprintf(output, msg_table[30], count); // %d players found.
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[30], count); // %d players found.
+ clif_displaymessage(fd, atcmd_output);
}
return 0;
@@ -1238,14 +1289,15 @@ int atcommand_who2(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char output[200];
struct map_session_data *pl_sd;
int i, j, count;
int pl_GM_level, GM_level;
char match_text[100];
char player_name[24];
- memset(output, '\0', sizeof(output));
+ nullpo_retr(-1, sd);
+
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
memset(match_text, '\0', sizeof(match_text));
memset(player_name, '\0', sizeof(player_name));
@@ -1257,7 +1309,7 @@ int atcommand_who2(
count = 0;
GM_level = pc_isGM(sd);
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) {
pl_GM_level = pc_isGM(pl_sd);
if (!((battle_config.hide_GM_session || (pl_sd->status.option & OPTION_HIDE)) && (pl_GM_level > GM_level))) { // you can look only lower or same level
memcpy(player_name, pl_sd->status.name, 24);
@@ -1265,10 +1317,10 @@ int atcommand_who2(
player_name[j] = tolower(player_name[j]);
if (strstr(player_name, match_text) != NULL) { // search with no case sensitive
if (pl_GM_level > 0)
- sprintf(output, "Name: %s (GM:%d) | BLvl: %d | Job: %s (Lvl: %d)", pl_sd->status.name, pl_GM_level, pl_sd->status.base_level, job_name(pl_sd->status.class), pl_sd->status.job_level);
+ sprintf(atcmd_output, "Name: %s (GM:%d) | BLvl: %d | Job: %s (Lvl: %d)", pl_sd->status.name, pl_GM_level, pl_sd->status.base_level, job_name(pl_sd->status.class_), pl_sd->status.job_level);
else
- sprintf(output, "Name: %s | BLvl: %d | Job: %s (Lvl: %d)", pl_sd->status.name, pl_sd->status.base_level, job_name(pl_sd->status.class), pl_sd->status.job_level);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Name: %s | BLvl: %d | Job: %s (Lvl: %d)", pl_sd->status.name, pl_sd->status.base_level, job_name(pl_sd->status.class_), pl_sd->status.job_level);
+ clif_displaymessage(fd, atcmd_output);
count++;
}
}
@@ -1280,8 +1332,8 @@ int atcommand_who2(
else if (count == 1)
clif_displaymessage(fd, msg_table[29]); // 1 player found.
else {
- sprintf(output, msg_table[30], count); // %d players found.
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[30], count); // %d players found.
+ clif_displaymessage(fd, atcmd_output);
}
return 0;
@@ -1297,7 +1349,6 @@ int atcommand_who3(
{
char temp0[100];
char temp1[100];
- char output[200];
struct map_session_data *pl_sd;
int i, j, count;
int pl_GM_level, GM_level;
@@ -1306,9 +1357,11 @@ int atcommand_who3(
struct guild *g;
struct party *p;
+ nullpo_retr(-1, sd);
+
memset(temp0, '\0', sizeof(temp0));
memset(temp1, '\0', sizeof(temp1));
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
memset(match_text, '\0', sizeof(match_text));
memset(player_name, '\0', sizeof(player_name));
@@ -1320,7 +1373,7 @@ int atcommand_who3(
count = 0;
GM_level = pc_isGM(sd);
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) {
pl_GM_level = pc_isGM(pl_sd);
if (!((battle_config.hide_GM_session || (pl_sd->status.option & OPTION_HIDE)) && (pl_GM_level > GM_level))) { // you can look only lower or same level
memcpy(player_name, pl_sd->status.name, 24);
@@ -1338,10 +1391,10 @@ int atcommand_who3(
else
sprintf(temp0, "%s", p->name);
if (pl_GM_level > 0)
- sprintf(output, "Name: %s (GM:%d) | Party: '%s' | Guild: '%s'", pl_sd->status.name, pl_GM_level, temp0, temp1);
+ sprintf(atcmd_output, "Name: %s (GM:%d) | Party: '%s' | Guild: '%s'", pl_sd->status.name, pl_GM_level, temp0, temp1);
else
- sprintf(output, "Name: %s | Party: '%s' | Guild: '%s'", pl_sd->status.name, temp0, temp1);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Name: %s | Party: '%s' | Guild: '%s'", pl_sd->status.name, temp0, temp1);
+ clif_displaymessage(fd, atcmd_output);
count++;
}
}
@@ -1353,8 +1406,8 @@ int atcommand_who3(
else if (count == 1)
clif_displaymessage(fd, msg_table[29]); // 1 player found.
else {
- sprintf(output, msg_table[30], count); // %d players found.
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[30], count); // %d players found.
+ clif_displaymessage(fd, atcmd_output);
}
return 0;
@@ -1368,14 +1421,13 @@ int atcommand_whomap(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char output[200];
struct map_session_data *pl_sd;
int i, count;
int pl_GM_level, GM_level;
int map_id;
char map_name[100];
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
memset(map_name, '\0', sizeof(map_name));
if (!message || !*message)
@@ -1391,15 +1443,15 @@ int atcommand_whomap(
count = 0;
GM_level = pc_isGM(sd);
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) {
pl_GM_level = pc_isGM(pl_sd);
if (!((battle_config.hide_GM_session || (pl_sd->status.option & OPTION_HIDE)) && (pl_GM_level > GM_level))) { // you can look only lower or same level
if (pl_sd->bl.m == map_id) {
if (pl_GM_level > 0)
- sprintf(output, "Name: %s (GM:%d) | Location: %s %d %d", pl_sd->status.name, pl_GM_level, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y);
+ sprintf(atcmd_output, "Name: %s (GM:%d) | Location: %s %d %d", pl_sd->status.name, pl_GM_level, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y);
else
- sprintf(output, "Name: %s | Location: %s %d %d", pl_sd->status.name, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Name: %s | Location: %s %d %d", pl_sd->status.name, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y);
+ clif_displaymessage(fd, atcmd_output);
count++;
}
}
@@ -1407,13 +1459,13 @@ int atcommand_whomap(
}
if (count == 0)
- sprintf(output, msg_table[54], map[map_id].name); // No player found in map '%s'.
+ sprintf(atcmd_output, msg_table[54], map[map_id].name); // No player found in map '%s'.
else if (count == 1)
- sprintf(output, msg_table[55], map[map_id].name); // 1 player found in map '%s'.
+ sprintf(atcmd_output, msg_table[55], map[map_id].name); // 1 player found in map '%s'.
else {
- sprintf(output, msg_table[56], count, map[map_id].name); // %d players found in map '%s'.
+ sprintf(atcmd_output, msg_table[56], count, map[map_id].name); // %d players found in map '%s'.
}
- clif_displaymessage(fd, output);
+ clif_displaymessage(fd, atcmd_output);
return 0;
}
@@ -1426,14 +1478,15 @@ int atcommand_whomap2(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char output[200];
struct map_session_data *pl_sd;
int i, count;
int pl_GM_level, GM_level;
int map_id = 0;
char map_name[100];
- memset(output, '\0', sizeof(output));
+ nullpo_retr(-1, sd);
+
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
memset(map_name, '\0', sizeof(map_name));
if (!message || !*message)
@@ -1449,15 +1502,15 @@ int atcommand_whomap2(
count = 0;
GM_level = pc_isGM(sd);
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) {
pl_GM_level = pc_isGM(pl_sd);
if (!((battle_config.hide_GM_session || (pl_sd->status.option & OPTION_HIDE)) && (pl_GM_level > GM_level))) { // you can look only lower or same level
if (pl_sd->bl.m == map_id) {
if (pl_GM_level > 0)
- sprintf(output, "Name: %s (GM:%d) | BLvl: %d | Job: %s (Lvl: %d)", pl_sd->status.name, pl_GM_level, pl_sd->status.base_level, job_name(pl_sd->status.class), pl_sd->status.job_level);
+ sprintf(atcmd_output, "Name: %s (GM:%d) | BLvl: %d | Job: %s (Lvl: %d)", pl_sd->status.name, pl_GM_level, pl_sd->status.base_level, job_name(pl_sd->status.class_), pl_sd->status.job_level);
else
- sprintf(output, "Name: %s | BLvl: %d | Job: %s (Lvl: %d)", pl_sd->status.name, pl_sd->status.base_level, job_name(pl_sd->status.class), pl_sd->status.job_level);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Name: %s | BLvl: %d | Job: %s (Lvl: %d)", pl_sd->status.name, pl_sd->status.base_level, job_name(pl_sd->status.class_), pl_sd->status.job_level);
+ clif_displaymessage(fd, atcmd_output);
count++;
}
}
@@ -1465,13 +1518,13 @@ int atcommand_whomap2(
}
if (count == 0)
- sprintf(output, msg_table[54], map[map_id].name); // No player found in map '%s'.
+ sprintf(atcmd_output, msg_table[54], map[map_id].name); // No player found in map '%s'.
else if (count == 1)
- sprintf(output, msg_table[55], map[map_id].name); // 1 player found in map '%s'.
+ sprintf(atcmd_output, msg_table[55], map[map_id].name); // 1 player found in map '%s'.
else {
- sprintf(output, msg_table[56], count, map[map_id].name); // %d players found in map '%s'.
+ sprintf(atcmd_output, msg_table[56], count, map[map_id].name); // %d players found in map '%s'.
}
- clif_displaymessage(fd, output);
+ clif_displaymessage(fd, atcmd_output);
return 0;
}
@@ -1486,7 +1539,6 @@ int atcommand_whomap3(
{
char temp0[100];
char temp1[100];
- char output[200];
struct map_session_data *pl_sd;
int i, count;
int pl_GM_level, GM_level;
@@ -1495,9 +1547,11 @@ int atcommand_whomap3(
struct guild *g;
struct party *p;
+ nullpo_retr(-1, sd);
+
memset(temp0, '\0', sizeof(temp0));
memset(temp1, '\0', sizeof(temp1));
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
memset(map_name, '\0', sizeof(map_name));
if (!message || !*message)
@@ -1513,7 +1567,7 @@ int atcommand_whomap3(
count = 0;
GM_level = pc_isGM(sd);
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) {
pl_GM_level = pc_isGM(pl_sd);
if (!((battle_config.hide_GM_session || (pl_sd->status.option & OPTION_HIDE)) && (pl_GM_level > GM_level))) { // you can look only lower or same level
if (pl_sd->bl.m == map_id) {
@@ -1528,10 +1582,10 @@ int atcommand_whomap3(
else
sprintf(temp0, "%s", p->name);
if (pl_GM_level > 0)
- sprintf(output, "Name: %s (GM:%d) | Party: '%s' | Guild: '%s'", pl_sd->status.name, pl_GM_level, temp0, temp1);
+ sprintf(atcmd_output, "Name: %s (GM:%d) | Party: '%s' | Guild: '%s'", pl_sd->status.name, pl_GM_level, temp0, temp1);
else
- sprintf(output, "Name: %s | Party: '%s' | Guild: '%s'", pl_sd->status.name, temp0, temp1);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Name: %s | Party: '%s' | Guild: '%s'", pl_sd->status.name, temp0, temp1);
+ clif_displaymessage(fd, atcmd_output);
count++;
}
}
@@ -1539,13 +1593,13 @@ int atcommand_whomap3(
}
if (count == 0)
- sprintf(output, msg_table[54], map[map_id].name); // No player found in map '%s'.
+ sprintf(atcmd_output, msg_table[54], map[map_id].name); // No player found in map '%s'.
else if (count == 1)
- sprintf(output, msg_table[55], map[map_id].name); // 1 player found in map '%s'.
+ sprintf(atcmd_output, msg_table[55], map[map_id].name); // 1 player found in map '%s'.
else {
- sprintf(output, msg_table[56], count, map[map_id].name); // %d players found in map '%s'.
+ sprintf(atcmd_output, msg_table[56], count, map[map_id].name); // %d players found in map '%s'.
}
- clif_displaymessage(fd, output);
+ clif_displaymessage(fd, atcmd_output);
return 0;
}
@@ -1560,7 +1614,6 @@ int atcommand_whogm(
{
char temp0[100];
char temp1[100];
- char output[200];
struct map_session_data *pl_sd;
int i, j, count;
int pl_GM_level, GM_level;
@@ -1569,9 +1622,11 @@ int atcommand_whogm(
struct guild *g;
struct party *p;
+ nullpo_retr(-1, sd);
+
memset(temp0, '\0', sizeof(temp0));
memset(temp1, '\0', sizeof(temp1));
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
memset(match_text, '\0', sizeof(match_text));
memset(player_name, '\0', sizeof(player_name));
@@ -1583,7 +1638,7 @@ int atcommand_whogm(
count = 0;
GM_level = pc_isGM(sd);
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) {
pl_GM_level = pc_isGM(pl_sd);
if (pl_GM_level > 0) {
if (!((battle_config.hide_GM_session || (pl_sd->status.option & OPTION_HIDE)) && (pl_GM_level > GM_level))) { // you can look only lower or same level
@@ -1591,10 +1646,10 @@ int atcommand_whogm(
for (j = 0; player_name[j]; j++)
player_name[j] = tolower(player_name[j]);
if (strstr(player_name, match_text) != NULL) { // search with no case sensitive
- sprintf(output, "Name: %s (GM:%d) | Location: %s %d %d", pl_sd->status.name, pl_GM_level, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y);
- clif_displaymessage(fd, output);
- sprintf(output, " BLvl: %d | Job: %s (Lvl: %d)", pl_sd->status.base_level, job_name(pl_sd->status.class), pl_sd->status.job_level);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Name: %s (GM:%d) | Location: %s %d %d", pl_sd->status.name, pl_GM_level, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y);
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, " BLvl: %d | Job: %s (Lvl: %d)", pl_sd->status.base_level, job_name(pl_sd->status.class_), pl_sd->status.job_level);
+ clif_displaymessage(fd, atcmd_output);
g = guild_search(pl_sd->status.guild_id);
if (g == NULL)
sprintf(temp1, "None");
@@ -1605,8 +1660,8 @@ int atcommand_whogm(
sprintf(temp0, "None");
else
sprintf(temp0, "%s", p->name);
- sprintf(output, " Party: '%s' | Guild: '%s'", temp0, temp1);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, " Party: '%s' | Guild: '%s'", temp0, temp1);
+ clif_displaymessage(fd, atcmd_output);
count++;
}
}
@@ -1619,8 +1674,8 @@ int atcommand_whogm(
else if (count == 1)
clif_displaymessage(fd, msg_table[151]); // 1 GM found.
else {
- sprintf(output, msg_table[152], count); // %d GMs found.
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[152], count); // %d GMs found.
+ clif_displaymessage(fd, atcmd_output);
}
return 0;
@@ -1630,15 +1685,18 @@ int atcommand_whozeny(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char output[200];
struct map_session_data *pl_sd;
int i, j, count,c;
char match_text[100];
char player_name[24];
- int zeny[clif_countusers()];
- int counted[clif_countusers()];
+ //int zeny[clif_countusers()];
+ //int counted[clif_countusers()];
+ int *zeny = (int *)aCallocA(clif_countusers(), sizeof(int));
+ int *counted = (int *)aCallocA(clif_countusers(), sizeof(int));
+
+ nullpo_retr(-1, sd);
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
memset(match_text, '\0', sizeof(match_text));
memset(player_name, '\0', sizeof(player_name));
@@ -1649,7 +1707,7 @@ int atcommand_whozeny(
count = 0;
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) {
memcpy(player_name, pl_sd->status.name, 24);
for (j = 0; player_name[j]; j++)
player_name[j] = tolower(player_name[j]);
@@ -1668,10 +1726,10 @@ int atcommand_whozeny(
for (i = 0; i < fd_max; i++) {
if(!zeny[c])
continue;
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth && zeny[c] && counted[i]==0) {
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && zeny[c] && counted[i]==0) {
if(pl_sd->status.zeny==zeny[c]) {
- sprintf(output, "Name: %s | Zeny: %d", pl_sd->status.name, pl_sd->status.zeny);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Name: %s | Zeny: %d", pl_sd->status.name, pl_sd->status.zeny);
+ clif_displaymessage(fd, atcmd_output);
zeny[c]=0;
counted[i]=1;
}
@@ -1684,10 +1742,13 @@ int atcommand_whozeny(
else if (count == 1)
clif_displaymessage(fd, msg_table[29]); // 1 player found.
else {
- sprintf(output, msg_table[30], count); // %d players found.
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[30], count); // %d players found.
+ clif_displaymessage(fd, atcmd_output);
}
+ aFree(zeny);
+ aFree(counted);
+
return 0;
}
@@ -1697,14 +1758,15 @@ int atcommand_happyhappyjoyjoy(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
-
struct map_session_data *pl_sd;
int i,e;
+ nullpo_retr(-1, sd);
+
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) {
e=rand()%40;
- if(e==34)
+ if(e==34)
e = 0;
clif_emotion(&pl_sd->bl,e);
}
@@ -1721,6 +1783,8 @@ int atcommand_save(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
+
pc_setsavepoint(sd, sd->mapname, sd->bl.x, sd->bl.y);
if (sd->status.pet_id > 0 && sd->pd)
intif_save_petdata(sd->status.account_id, &sd->pet);
@@ -1742,13 +1806,15 @@ int atcommand_load(
{
int m;
+ nullpo_retr(-1, sd);
+
m = map_mapname2mapid(sd->status.save_point.map);
if (m >= 0 && map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
- clif_displaymessage(fd, "You are not authorised to warp you to your save map.");
+ clif_displaymessage(fd, msg_table[249]);
return -1;
}
if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
- clif_displaymessage(fd, "You are not authorised to warp you from your actual map.");
+ clif_displaymessage(fd, msg_table[248]);
return -1;
}
@@ -1766,14 +1832,15 @@ int atcommand_speed(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char output[200];
int speed;
- memset(output, '\0', sizeof(output));
+ nullpo_retr(-1, sd);
+
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message) {
- sprintf(output, "Please, enter a speed value (usage: @speed <%d-%d>).", MIN_WALK_SPEED, MAX_WALK_SPEED);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Please, enter a speed value (usage: @speed <%d-%d>).", MIN_WALK_SPEED, MAX_WALK_SPEED);
+ clif_displaymessage(fd, atcmd_output);
return -1;
}
@@ -1785,8 +1852,8 @@ int atcommand_speed(
clif_updatestatus(sd, SP_SPEED);
clif_displaymessage(fd, msg_table[8]); // Speed changed.
} else {
- sprintf(output, "Please, enter a valid speed value (usage: @speed <%d-%d>).", MIN_WALK_SPEED, MAX_WALK_SPEED);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Please, enter a valid speed value (usage: @speed <%d-%d>).", MIN_WALK_SPEED, MAX_WALK_SPEED);
+ clif_displaymessage(fd, atcmd_output);
return -1;
}
@@ -1801,11 +1868,25 @@ int atcommand_storage(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ struct storage *stor; //changes from Freya/Yor
+ nullpo_retr(-1, sd);
+
+ if (sd->state.storage_flag == 1) {
+ clif_displaymessage(fd, msg_table[250]);
+ return -1;
+ }
+
+ if ((stor = account2storage2(sd->status.account_id)) != NULL && stor->storage_status == 1) {
+ clif_displaymessage(fd, msg_table[250]);
+ return -1;
+ }
+
storage_storageopen(sd);
return 0;
}
+
/*==========================================
*
*------------------------------------------
@@ -1814,8 +1895,23 @@ int atcommand_guildstorage(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- if (sd->status.guild_id > 0)
+ struct storage *stor; //changes from Freya/Yor
+ nullpo_retr(-1, sd);
+
+ if (sd->status.guild_id > 0) {
+ if (sd->state.storage_flag == 1) {
+ clif_displaymessage(fd, msg_table[251]);
+ return -1;
+ }
+ if ((stor = account2storage2(sd->status.account_id)) != NULL && stor->storage_status == 1) {
+ clif_displaymessage(fd, msg_table[251]);
+ return -1;
+ }
storage_guild_storageopen(sd);
+ } else {
+ clif_displaymessage(fd, msg_table[252]);
+ return -1;
+ }
return 0;
}
@@ -1829,6 +1925,7 @@ int atcommand_option(
const char* command, const char* message)
{
int param1 = 0, param2 = 0, param3 = 0;
+ nullpo_retr(-1, sd);
if (!message || !*message || sscanf(message, "%d %d %d", &param1, &param2, &param3) < 1 || param1 < 0 || param2 < 0 || param3 < 0) {
clif_displaymessage(fd, "Please, enter at least a option (usage: @option <param1:0+> <param2:0+> <param3:0+>).");
@@ -1844,30 +1941,30 @@ int atcommand_option(
}
sd->status.option = param3;
// fix pecopeco display
- if (sd->status.class == 13 || sd->status.class == 21 || sd->status.class == 4014 || sd->status.class == 4022) {
+ if (sd->status.class_ == 13 || sd->status.class_ == 21 || sd->status.class_ == 4014 || sd->status.class_ == 4022) {
if (!pc_isriding(sd)) { // sd have the new value...
- if (sd->status.class == 13)
- sd->status.class = sd->view_class = 7;
- else if (sd->status.class == 21)
- sd->status.class = sd->view_class = 14;
- else if (sd->status.class == 4014)
- sd->status.class = sd->view_class = 4008;
- else if (sd->status.class == 4022)
- sd->status.class = sd->view_class = 4015;
+ if (sd->status.class_ == 13)
+ sd->status.class_ = sd->view_class = 7;
+ else if (sd->status.class_ == 21)
+ sd->status.class_ = sd->view_class = 14;
+ else if (sd->status.class_ == 4014)
+ sd->status.class_ = sd->view_class = 4008;
+ else if (sd->status.class_ == 4022)
+ sd->status.class_ = sd->view_class = 4015;
}
} else {
if (pc_isriding(sd)) { // sd have the new value...
if (sd->disguise > 0) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris] (code added by [Yor])
sd->status.option &= ~0x0020;
} else {
- if (sd->status.class == 7)
- sd->status.class = sd->view_class = 13;
- else if (sd->status.class == 14)
- sd->status.class = sd->view_class = 21;
- else if (sd->status.class == 4008)
- sd->status.class = sd->view_class = 4014;
- else if (sd->status.class == 4015)
- sd->status.class = sd->view_class = 4022;
+ if (sd->status.class_ == 7)
+ sd->status.class_ = sd->view_class = 13;
+ else if (sd->status.class_ == 14)
+ sd->status.class_ = sd->view_class = 21;
+ else if (sd->status.class_ == 4008)
+ sd->status.class_ = sd->view_class = 4014;
+ else if (sd->status.class_ == 4015)
+ sd->status.class_ = sd->view_class = 4022;
else
sd->status.option &= ~0x0020;
}
@@ -1875,7 +1972,7 @@ int atcommand_option(
}
clif_changeoption(&sd->bl);
- pc_calcstatus(sd, 0);
+ status_calc_pc(sd, 0);
clif_displaymessage(fd, msg_table[9]); // Options changed.
return 0;
@@ -1889,6 +1986,7 @@ int atcommand_hide(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
if (sd->status.option & OPTION_HIDE) {
sd->status.option &= ~OPTION_HIDE;
clif_displaymessage(fd, msg_table[10]); // Invisible: Off
@@ -1909,32 +2007,116 @@ int atcommand_jobchange(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- int job = 0, upper = -1;
+ int job = 0, upper = 0;
+ nullpo_retr(-1, sd);
if (!message || !*message || sscanf(message, "%d %d", &job, &upper) < 1) {
- clif_displaymessage(fd, "Please, enter job ID (usage: @job/@jobchange <job ID>).");
- return -1;
+
+ int i, found = 0;
+ const struct { char name[16]; int id; } jobs[] = {
+ { "novice", 0 },
+ { "swordsman", 1 },
+ { "mage", 2 },
+ { "archer", 3 },
+ { "acolyte", 4 },
+ { "merchant", 5 },
+ { "thief", 6 },
+ { "knight", 7 },
+ { "priest", 8 },
+ { "priestess", 8 },
+ { "wizard", 9 },
+ { "blacksmith", 10 },
+ { "hunter", 11 },
+ { "assassin", 12 },
+ { "crusader", 14 },
+ { "monk", 15 },
+ { "sage", 16 },
+ { "rogue", 17 },
+ { "alchemist", 18 },
+ { "bard", 19 },
+ { "dancer", 20 },
+ { "super novice", 23 },
+ { "supernovice", 23 },
+ { "high novice", 4001 },
+ { "swordsman high", 4002 },
+ { "mage high", 4003 },
+ { "archer high", 4004 },
+ { "acolyte high", 4005 },
+ { "merchant high", 4006 },
+ { "thief high", 4007 },
+ { "lord knight", 4008 },
+ { "high priest", 4009 },
+ { "high priestess", 4009 },
+ { "high wizard", 4010 },
+ { "whitesmith", 4011 },
+ { "sniper", 4012 },
+ { "assassin cross", 4013 },
+ { "paladin", 4015 },
+ { "champion", 4016 },
+ { "professor", 4017 },
+ { "stalker", 4018 },
+ { "creator", 4019 },
+ { "clown", 4020 },
+ { "gypsy", 4021 },
+ { "baby novice", 4023 },
+ { "baby swordsman", 4024 },
+ { "baby mage", 4025 },
+ { "baby archer", 4026 },
+ { "baby acolyte", 4027 },
+ { "baby merchant", 4028 },
+ { "baby thief", 4029 },
+ { "baby knight", 4030 },
+ { "baby priest", 4031 },
+ { "baby priestess", 4031 },
+ { "baby wizard", 4032 },
+ { "baby blacksmith",4033 },
+ { "baby hunter", 4034 },
+ { "baby assassin", 4035 },
+ { "baby crusader", 4037 },
+ { "baby monk", 4038 },
+ { "baby sage", 4039 },
+ { "baby rogue", 4040 },
+ { "baby alchemist", 4041 },
+ { "baby bard", 4042 },
+ { "baby dancer", 4043 },
+ { "super baby", 4045 },
+ };
+
+ for (i=0; i < (int)(sizeof(jobs) / sizeof(jobs[0])); i++) {
+ if (strncmpi(message, jobs[i].name, 16) == 0) {
+ job = jobs[i].id;
+ upper = 0;
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ clif_displaymessage(fd, "Please, enter job ID (usage: @job/@jobchange <job ID>).");
+ return -1;
+ }
}
if (job == 37 ||job == 45)
return 0;
if ((job >= 0 && job < MAX_PC_CLASS)) {
+ int j;
// fix pecopeco display
if ((job != 13 && job != 21 && job != 4014 && job != 4022)) {
if (pc_isriding(sd)) {
- if (sd->status.class == 13)
- sd->status.class = sd->view_class = 7;
- if (sd->status.class == 21)
- sd->status.class = sd->view_class = 14;
- if (sd->status.class == 4014)
- sd->status.class = sd->view_class = 4008;
- if (sd->status.class == 4022)
- sd->status.class = sd->view_class = 4015;
+ if (sd->status.class_ == 13)
+ sd->status.class_ = sd->view_class = 7;
+ if (sd->status.class_ == 21)
+ sd->status.class_ = sd->view_class = 14;
+ if (sd->status.class_ == 4014)
+ sd->status.class_ = sd->view_class = 4008;
+ if (sd->status.class_ == 4022)
+ sd->status.class_ = sd->view_class = 4015;
sd->status.option &= ~0x0020;
clif_changeoption(&sd->bl);
- pc_calcstatus(sd, 0);
+ status_calc_pc(sd, 0);
}
} else {
if (!pc_isriding(sd)) {
@@ -1948,7 +2130,10 @@ int atcommand_jobchange(
job = 4015;
}
}
-
+ for (j=0; j < MAX_INVENTORY; j++) {
+ if(sd->status.inventory[j].nameid>0 && sd->status.inventory[j].equip!=0)
+ pc_unequipitem(sd, j, 3);
+ }
if (pc_jobchange(sd, job, upper) == 0)
clif_displaymessage(fd, msg_table[12]); // Your job has been changed.
else {
@@ -1971,6 +2156,7 @@ int atcommand_die(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
clif_specialeffect(&sd->bl,450,1);
pc_damage(NULL, sd, sd->status.hp + 1);
clif_displaymessage(fd, msg_table[13]); // A pity! You've died.
@@ -1986,17 +2172,17 @@ int atcommand_kill(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
struct map_session_data *pl_sd;
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
clif_displaymessage(fd, "Please, enter a player name (usage: @kill <char name>).");
return -1;
}
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can kill only lower or same level
pc_damage(NULL, pl_sd, pl_sd->status.hp + 1);
clif_displaymessage(fd, msg_table[14]); // Character killed.
@@ -2020,6 +2206,7 @@ int atcommand_alive(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
if (pc_isdead(sd)) {
sd->status.hp = sd->status.max_hp;
sd->status.sp = sd->status.max_sp;
@@ -2032,9 +2219,8 @@ int atcommand_alive(
clif_resurrection(&sd->bl, 1);
clif_displaymessage(fd, msg_table[16]); // You've been revived! It's a miracle!
return 0;
- }
+ }
return -1;
-
}
/*==========================================
@@ -2045,17 +2231,17 @@ int atcommand_kami(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char output[200];
+ nullpo_retr(-1, sd);
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message) {
clif_displaymessage(fd, "Please, enter a message (usage: @kami <message>).");
return -1;
}
- sscanf(message, "%199[^\n]", output);
- intif_GMmessage(output, strlen(output) + 1, (*(command + 5) == 'b') ? 0x10 : 0);
+ sscanf(message, "%199[^\n]", atcmd_output);
+ intif_GMmessage(atcmd_output, strlen(atcmd_output) + 1, (*(command + 5) == 'b') ? 0x10 : 0);
return 0;
}
@@ -2069,6 +2255,7 @@ int atcommand_heal(
const char* command, const char* message)
{
int hp = 0, sp = 0; // [Valaris] thanks to fov
+ nullpo_retr(-1, sd);
sscanf(message, "%d %d", &hp, &sp);
@@ -2120,6 +2307,7 @@ int atcommand_item(
struct item item_tmp;
struct item_data *item_data;
int get_count, i, pet_id;
+ nullpo_retr(-1, sd);
memset(item_name, '\0', sizeof(item_name));
@@ -2147,10 +2335,10 @@ int atcommand_item(
for (i = 0; i < number; i += get_count) {
// if pet egg
if (pet_id >= 0) {
- sd->catch_target_class = pet_db[pet_id].class;
+ sd->catch_target_class = pet_db[pet_id].class_;
intif_create_pet(sd->status.account_id, sd->status.char_id,
- pet_db[pet_id].class, mob_db[pet_db[pet_id].class].lv,
- pet_db[pet_id].EggID, 0, pet_db[pet_id].intimate,
+ (short)pet_db[pet_id].class_, (short)mob_db[pet_db[pet_id].class_].lv,
+ (short)pet_db[pet_id].EggID, 0, (short)pet_db[pet_id].intimate,
100, 0, 1, pet_db[pet_id].jname);
// if not pet egg
} else {
@@ -2186,6 +2374,7 @@ int atcommand_item2(
int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
int flag;
int loop, get_count, i;
+ nullpo_retr(-1, sd);
memset(item_name, '\0', sizeof(item_name));
@@ -2253,6 +2442,7 @@ int atcommand_itemreset(
const char* command, const char* message)
{
int i;
+ nullpo_retr(-1, sd);
for (i = 0; i < MAX_INVENTORY; i++) {
if (sd->status.inventory[i].amount && sd->status.inventory[i].equip == 0)
@@ -2271,6 +2461,7 @@ int atcommand_itemcheck(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
pc_checkitem(sd);
return 0;
@@ -2285,6 +2476,7 @@ int atcommand_baselevelup(
const char* command, const char* message)
{
int level, i;
+ nullpo_retr(-1, sd);
if (!message || !*message || (level = atoi(message)) == 0) {
clif_displaymessage(fd, "Please, enter a level adjustement (usage: @lvup/@blevel/@baselvlup <number of levels>).");
@@ -2296,7 +2488,7 @@ int atcommand_baselevelup(
clif_displaymessage(fd, msg_table[47]); // Base level can't go any higher.
return -1;
} // End Addition
- if (level > battle_config.maximum_level || level > (battle_config.maximum_level - sd->status.base_level)) // fix positiv overflow
+ if ((unsigned int)level > battle_config.maximum_level || (unsigned int)level > (battle_config.maximum_level - sd->status.base_level)) // fix positiv overflow
level = battle_config.maximum_level - sd->status.base_level;
for (i = 1; i <= level; i++)
sd->status.status_point += (sd->status.base_level + i + 14) / 5;
@@ -2304,7 +2496,7 @@ int atcommand_baselevelup(
clif_updatestatus(sd, SP_BASELEVEL);
clif_updatestatus(sd, SP_NEXTBASEEXP);
clif_updatestatus(sd, SP_STATUSPOINT);
- pc_calcstatus(sd, 0);
+ status_calc_pc(sd, 0);
pc_heal(sd, sd->status.max_hp, sd->status.max_sp);
clif_misceffect(&sd->bl, 0);
clif_displaymessage(fd, msg_table[21]); // Base level raised.
@@ -2313,7 +2505,7 @@ int atcommand_baselevelup(
clif_displaymessage(fd, msg_table[158]); // Base level can't go any lower.
return -1;
}
- if (level < -battle_config.maximum_level || level < (1 - sd->status.base_level)) // fix negativ overflow
+ if (level < -(int)battle_config.maximum_level || level < (1 - (int)sd->status.base_level)) // fix negativ overflow
level = 1 - sd->status.base_level;
if (sd->status.status_point > 0) {
for (i = 0; i > level; i--)
@@ -2325,7 +2517,7 @@ int atcommand_baselevelup(
sd->status.base_level += level;
clif_updatestatus(sd, SP_BASELEVEL);
clif_updatestatus(sd, SP_NEXTBASEEXP);
- pc_calcstatus(sd, 0);
+ status_calc_pc(sd, 0);
clif_displaymessage(fd, msg_table[22]); // Base level lowered.
}
@@ -2340,16 +2532,23 @@ int atcommand_joblevelup(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- int up_level = 50, level;
+ unsigned int up_level = 50;
+ int level;
+ struct pc_base_job s_class;
+ nullpo_retr(-1, sd);
+ s_class = pc_calc_base_job(sd->status.class_);
if (!message || !*message || (level = atoi(message)) == 0) {
clif_displaymessage(fd, "Please, enter a level adjustement (usage: @joblvup/@jlevel/@joblvlup <number of levels>).");
return -1;
}
- if (sd->status.class == 0 || sd->status.class == 4001)
+ if (s_class.job == 0)
up_level -= 40;
- else if ((sd->status.class > 4007 && sd->status.class < 4024) || sd->status.class == 23)
+ // super novices can go up to 99 [celest]
+ else if (s_class.job == 23)
+ up_level += 49;
+ else if (sd->status.class_ > 4007 && sd->status.class_ < 4023)
up_level += 20;
if (level > 0) {
@@ -2357,14 +2556,14 @@ int atcommand_joblevelup(
clif_displaymessage(fd, msg_table[23]); // Job level can't go any higher.
return -1;
}
- if (level > up_level || level > (up_level - sd->status.job_level)) // fix positiv overflow
+ if ((unsigned int)level > up_level || (unsigned int)level > (up_level - sd->status.job_level)) // fix positiv overflow
level = up_level - sd->status.job_level;
sd->status.job_level += level;
clif_updatestatus(sd, SP_JOBLEVEL);
clif_updatestatus(sd, SP_NEXTJOBEXP);
sd->status.skill_point += level;
clif_updatestatus(sd, SP_SKILLPOINT);
- pc_calcstatus(sd, 0);
+ status_calc_pc(sd, 0);
clif_misceffect(&sd->bl, 1);
clif_displaymessage(fd, msg_table[24]); // Job level raised.
} else {
@@ -2372,7 +2571,7 @@ int atcommand_joblevelup(
clif_displaymessage(fd, msg_table[159]); // Job level can't go any lower.
return -1;
}
- if (level < -up_level || level < (1 - sd->status.job_level)) // fix negativ overflow
+ if (level < -(int)up_level || level < (1 - (int)sd->status.job_level)) // fix negativ overflow
level = 1 - sd->status.job_level;
sd->status.job_level += level;
clif_updatestatus(sd, SP_JOBLEVEL);
@@ -2383,7 +2582,7 @@ int atcommand_joblevelup(
sd->status.skill_point = 0;
clif_updatestatus(sd, SP_SKILLPOINT);
} // to add: remove status points from skills
- pc_calcstatus(sd, 0);
+ status_calc_pc(sd, 0);
clif_displaymessage(fd, msg_table[25]); // Job level lowered.
}
@@ -2401,6 +2600,7 @@ int atcommand_help(
char buf[2048], w1[2048], w2[2048];
int i, gm_level;
FILE* fp;
+ nullpo_retr(-1, sd);
memset(buf, '\0', sizeof(buf));
@@ -2439,6 +2639,7 @@ int atcommand_gm(
const char* command, const char* message)
{
char password[100];
+ nullpo_retr(-1, sd);
memset(password, '\0', sizeof(password));
@@ -2466,6 +2667,7 @@ int atcommand_pvpoff(
{
struct map_session_data *pl_sd;
int i;
+ nullpo_retr(-1, sd);
if (battle_config.pk_mode) { //disable command if server is in PK mode [Valaris]
clif_displaymessage(fd, msg_table[52]); // This option cannot be used in PK Mode.
@@ -2476,7 +2678,7 @@ int atcommand_pvpoff(
map[sd->bl.m].flag.pvp = 0;
clif_send0199(sd->bl.m, 0);
for (i = 0; i < fd_max; i++) { //l”•ªƒ‹[ƒv
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) {
if (sd->bl.m == pl_sd->bl.m) {
clif_pvpset(pl_sd, 0, 0, 2);
if (pl_sd->pvp_timer != -1) {
@@ -2505,6 +2707,7 @@ int atcommand_pvpon(
{
struct map_session_data *pl_sd;
int i;
+ nullpo_retr(-1, sd);
if (battle_config.pk_mode) { //disable command if server is in PK mode [Valaris]
clif_displaymessage(fd, msg_table[52]); // This option cannot be used in PK Mode.
@@ -2515,7 +2718,7 @@ int atcommand_pvpon(
map[sd->bl.m].flag.pvp = 1;
clif_send0199(sd->bl.m, 1);
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) {
if (sd->bl.m == pl_sd->bl.m && pl_sd->pvp_timer == -1) {
pl_sd->pvp_timer = add_timer(gettick() + 200,
pc_calc_pvprank_timer, pl_sd->bl.id, 0);
@@ -2542,6 +2745,7 @@ int atcommand_gvgoff(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
if (map[sd->bl.m].flag.gvg) {
map[sd->bl.m].flag.gvg = 0;
clif_send0199(sd->bl.m, 0);
@@ -2562,6 +2766,7 @@ int atcommand_gvgon(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
if (!map[sd->bl.m].flag.gvg) {
map[sd->bl.m].flag.gvg = 1;
clif_send0199(sd->bl.m, 3);
@@ -2583,14 +2788,14 @@ int atcommand_model(
const char* command, const char* message)
{
int hair_style = 0, hair_color = 0, cloth_color = 0;
- char output[200];
+ nullpo_retr(-1, sd);
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message || sscanf(message, "%d %d %d", &hair_style, &hair_color, &cloth_color) < 1) {
- sprintf(output, "Please, enter at least a value (usage: @model <hair ID: %d-%d> <hair color: %d-%d> <clothes color: %d-%d>).",
+ sprintf(atcmd_output, "Please, enter at least a value (usage: @model <hair ID: %d-%d> <hair color: %d-%d> <clothes color: %d-%d>).",
MIN_HAIR_STYLE, MAX_HAIR_STYLE, MIN_HAIR_COLOR, MAX_HAIR_COLOR, MIN_CLOTH_COLOR, MAX_CLOTH_COLOR);
- clif_displaymessage(fd, output);
+ clif_displaymessage(fd, atcmd_output);
return -1;
}
@@ -2598,7 +2803,7 @@ int atcommand_model(
hair_color >= MIN_HAIR_COLOR && hair_color <= MAX_HAIR_COLOR &&
cloth_color >= MIN_CLOTH_COLOR && cloth_color <= MAX_CLOTH_COLOR) {
//•ž‚ÌF•ÏX
- if (cloth_color != 0 && sd->status.sex == 1 && (sd->status.class == 12 || sd->status.class == 17)) {
+ if (cloth_color != 0 && sd->status.sex == 1 && (sd->status.class_ == 12 || sd->status.class_ == 17)) {
//•ž‚ÌF–¢ŽÀ‘•E‚Ì”»’è
clif_displaymessage(fd, msg_table[35]); // You can't use this command with this class.
return -1;
@@ -2623,24 +2828,19 @@ int atcommand_model(
int atcommand_dye(const int fd, struct map_session_data* sd, const char* command, const char* message)
{
int cloth_color = 0;
- char output[200];
+ nullpo_retr(-1, sd);
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message || sscanf(message, "%d", &cloth_color) < 1) {
- sprintf(output, "Please, enter a clothes color (usage: @dye/@ccolor <clothes color: %d-%d>).", MIN_CLOTH_COLOR, MAX_CLOTH_COLOR);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Please, enter a clothes color (usage: @dye/@ccolor <clothes color: %d-%d>).", MIN_CLOTH_COLOR, MAX_CLOTH_COLOR);
+ clif_displaymessage(fd, atcmd_output);
return -1;
}
if (cloth_color >= MIN_CLOTH_COLOR && cloth_color <= MAX_CLOTH_COLOR) {
- if (cloth_color != 0 && sd->status.sex == 1 && (sd->status.class == 12 || sd->status.class == 17)) {
- clif_displaymessage(fd, msg_table[35]); // You can't use this command with this class.
- return -1;
- } else {
- pc_changelook(sd, LOOK_CLOTHES_COLOR, cloth_color);
- clif_displaymessage(fd, msg_table[36]); // Appearence changed.
- }
+ pc_changelook(sd, LOOK_CLOTHES_COLOR, cloth_color);
+ clif_displaymessage(fd, msg_table[36]); // Appearence changed.
} else {
clif_displaymessage(fd, msg_table[37]); // An invalid number was specified.
return -1;
@@ -2650,35 +2850,24 @@ int atcommand_dye(const int fd, struct map_session_data* sd, const char* command
}
/*==========================================
- * @chardye by [MouseJstr]
- *------------------------------------------
- */
-int
-atcommand_chardye(const int fd, struct map_session_data* sd,
- const char* command, const char* message)
-{
- return 0;
-}
-
-/*==========================================
* @hairstyle && @hstyle
*------------------------------------------
*/
int atcommand_hair_style(const int fd, struct map_session_data* sd, const char* command, const char* message)
{
int hair_style = 0;
- char output[200];
+ nullpo_retr(-1, sd);
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message || sscanf(message, "%d", &hair_style) < 1) {
- sprintf(output, "Please, enter a hair style (usage: @hairstyle/@hstyle <hair ID: %d-%d>).", MIN_HAIR_STYLE, MAX_HAIR_STYLE);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Please, enter a hair style (usage: @hairstyle/@hstyle <hair ID: %d-%d>).", MIN_HAIR_STYLE, MAX_HAIR_STYLE);
+ clif_displaymessage(fd, atcmd_output);
return -1;
}
if (hair_style >= MIN_HAIR_STYLE && hair_style <= MAX_HAIR_STYLE) {
- if (hair_style != 0 && sd->status.sex == 1 && (sd->status.class == 12 || sd->status.class == 17)) {
+ if (hair_style != 0 && sd->status.sex == 1 && (sd->status.class_ == 12 || sd->status.class_ == 17)) {
clif_displaymessage(fd, msg_table[35]); // You can't use this command with this class.
return -1;
} else {
@@ -2701,7 +2890,8 @@ int
atcommand_charhairstyle(const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- return 0;
+ nullpo_retr(-1, sd);
+ return 0;
}
/*==========================================
@@ -2711,18 +2901,18 @@ atcommand_charhairstyle(const int fd, struct map_session_data* sd,
int atcommand_hair_color(const int fd, struct map_session_data* sd, const char* command, const char* message)
{
int hair_color = 0;
- char output[200];
+ nullpo_retr(-1, sd);
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message || sscanf(message, "%d", &hair_color) < 1) {
- sprintf(output, "Please, enter a hair color (usage: @haircolor/@hcolor <hair color: %d-%d>).", MIN_HAIR_COLOR, MAX_HAIR_COLOR);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Please, enter a hair color (usage: @haircolor/@hcolor <hair color: %d-%d>).", MIN_HAIR_COLOR, MAX_HAIR_COLOR);
+ clif_displaymessage(fd, atcmd_output);
return -1;
}
if (hair_color >= MIN_HAIR_COLOR && hair_color <= MAX_HAIR_COLOR) {
- if (hair_color != 0 && sd->status.sex == 1 && (sd->status.class == 12 || sd->status.class == 17)) {
+ if (hair_color != 0 && sd->status.sex == 1 && (sd->status.class_ == 12 || sd->status.class_ == 17)) {
clif_displaymessage(fd, msg_table[35]); // You can't use this command with this class.
return -1;
} else {
@@ -2738,17 +2928,6 @@ int atcommand_hair_color(const int fd, struct map_session_data* sd, const char*
}
/*==========================================
- * @charhaircolor by [MouseJstr]
- *------------------------------------------
- */
-int
-atcommand_charhaircolor(const int fd, struct map_session_data* sd,
- const char* command, const char* message)
-{
- return 0;
-}
-
-/*==========================================
* @go [city_number/city_name]: improved by [yor] to add city names and help
*------------------------------------------
*/
@@ -2759,15 +2938,9 @@ int atcommand_go(
int i;
int town;
char map_name[100];
- char output[200];
int m;
- if(map[sd->bl.m].flag.nogo) {
- clif_displaymessage(sd->fd,"You can not use @go on this map.");
- return 0;
- }
-
- struct { char map[16]; int x, y; } data[] = {
+ const struct { char map[16]; int x, y; } data[] = {
{ "prontera.gat", 156, 191 }, // 0=Prontera
{ "morocc.gat", 156, 93 }, // 1=Morroc
{ "geffen.gat", 119, 59 }, // 2=Geffen
@@ -2785,10 +2958,19 @@ int atcommand_go(
{ "louyang.gat", 217, 40 }, // 14=Lou Yang
{ "new_1-1.gat", 53, 111 }, // 15=Start point
{ "sec_pri.gat", 23, 61 }, // 16=Prison
+ { "jawaii.gat", 249, 127 }, // 17=Jawaii
+ { "ayothaya.gat", 151, 117 }, // 18=Ayothaya
};
+ nullpo_retr(-1, sd);
+
+ if(map[sd->bl.m].flag.nogo) {
+ clif_displaymessage(sd->fd,"You can not use @go on this map.");
+ return 0;
+ }
+
memset(map_name, '\0', sizeof(map_name));
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
// get the number
town = atoi(message);
@@ -2803,7 +2985,8 @@ int atcommand_go(
clif_displaymessage(fd, " 0=Prontera 7=Lutie 14=Lou Yang");
clif_displaymessage(fd, " 1=Morroc 8=Comodo 15=Start point");
clif_displaymessage(fd, " 2=Geffen 9=Yuno 16=Prison");
- clif_displaymessage(fd, " 3=Payon 10=Amatsu");
+ clif_displaymessage(fd, " 3=Payon 10=Amatsu 17=Jawaii");
+ clif_displaymessage(fd, " 18=Ayothaya");
return -1;
} else {
// get possible name of the city and add .gat if not in the name
@@ -2858,17 +3041,23 @@ int atcommand_go(
strncmp(map_name, "prison.gat", 3) == 0 || // name of the position (3 first characters)
strncmp(map_name, "jails.gat", 3) == 0) { // name of the position
town = 16;
+ } else if (strncmp(map_name, "jawaii.gat", 3) == 0 || // 3 first characters
+ strncmp(map_name, "jawai.gat", 3) == 0) { // writing error (3 first characters)
+ town = 17;
+ } else if (strncmp(map_name, "ayothaya.gat", 4) == 0 || // 3 first characters
+ strncmp(map_name, "ayotaya.gat", 4) == 0) { // writing error (3 first characters)
+ town = 18;
}
if (town >= -3 && town <= -1) {
if (sd->status.memo_point[-town-1].map[0]) {
m = map_mapname2mapid(sd->status.memo_point[-town-1].map);
if (m >= 0 && map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
- clif_displaymessage(fd, "You are not authorised to warp you to this memo map.");
+ clif_displaymessage(fd, msg_table[247]);
return -1;
}
if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
- clif_displaymessage(fd, "You are not authorised to warp you from your actual map.");
+ clif_displaymessage(fd, msg_table[248]);
return -1;
}
if (pc_setpos(sd, sd->status.memo_point[-town-1].map, sd->status.memo_point[-town-1].x, sd->status.memo_point[-town-1].y, 3) == 0) {
@@ -2878,21 +3067,21 @@ int atcommand_go(
return -1;
}
} else {
- sprintf(output, msg_table[164], -town-1); // Your memo point #%d doesn't exist.
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[164], -town-1); // Your memo point #%d doesn't exist.
+ clif_displaymessage(fd, atcmd_output);
return -1;
}
} else if (town >= 0 && town < (int)(sizeof(data) / sizeof(data[0]))) {
- m = map_mapname2mapid(data[town].map);
+ m = map_mapname2mapid((char *)data[town].map);
if (m >= 0 && map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
- clif_displaymessage(fd, "You are not authorised to warp you to this destination map.");
+ clif_displaymessage(fd, msg_table[247]);
return -1;
}
if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
- clif_displaymessage(fd, "You are not authorised to warp you from your actual map.");
+ clif_displaymessage(fd, msg_table[248]);
return -1;
}
- if (pc_setpos(sd, data[town].map, data[town].x, data[town].y, 3) == 0) {
+ if (pc_setpos(sd, (char *)data[town].map, data[town].x, data[town].y, 3) == 0) {
clif_displaymessage(fd, msg_table[0]); // Warped.
} else {
clif_displaymessage(fd, msg_table[1]); // Map not found.
@@ -2917,17 +3106,17 @@ int atcommand_monster(
{
char name[100];
char monster[100];
- char output[200];
int mob_id;
int number = 0;
int x = 0, y = 0;
int count;
int i, j, k;
int mx, my, range;
+ nullpo_retr(-1, sd);
memset(name, '\0', sizeof(name));
memset(monster, '\0', sizeof(monster));
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message ||
(sscanf(message, "\"%[^\"]\" %99s %d %d %d", name, monster, &number, &x, &y) < 2 &&
@@ -2964,7 +3153,7 @@ int atcommand_monster(
printf("%s monster='%s' name='%s' id=%d count=%d (%d,%d)\n", command, monster, name, mob_id, number, x, y);
count = 0;
- range = sqrt(number) / 2;
+ range = (int)sqrt(number) / 2;
range = range * 2 + 5; // calculation of an odd number (+ 4 area around)
for (i = 0; i < number; i++) {
j = 0;
@@ -2987,8 +3176,8 @@ int atcommand_monster(
if (number == count)
clif_displaymessage(fd, msg_table[39]); // All monster summoned!
else {
- sprintf(output, msg_table[240], count); // %d monster(s) summoned!
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[240], count); // %d monster(s) summoned!
+ clif_displaymessage(fd, atcmd_output);
}
else {
clif_displaymessage(fd, msg_table[40]); // Invalid monster ID or name.
@@ -3007,7 +3196,6 @@ int atcommand_spawn(
const char* command, const char* message) {
char name[100];
char monster[100];
- char output[200];
int mob_id;
int number = 0;
int x = 0, y = 0;
@@ -3015,9 +3203,10 @@ int atcommand_spawn(
int i, j, k;
int mx, my, range;
+ nullpo_retr(-1, sd);
memset(name, '\0', sizeof(name));
memset(monster, '\0', sizeof(monster));
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message ||
(sscanf(message, "\"%[^\"]\" %99s %d %d %d", name, monster, &number, &x, &y) < 2 &&
@@ -3055,7 +3244,7 @@ int atcommand_spawn(
printf("%s monster='%s' name='%s' id=%d count=%d (%d,%d)\n", command, monster, name, mob_id, number, x, y);
count = 0;
- range = sqrt(number) / 2;
+ range = (int)sqrt(number) / 2;
range = range * 2 + 5; // calculation of an odd number (+ 4 area around)
for (i = 0; i < number; i++) {
j = 0;
@@ -3078,8 +3267,8 @@ int atcommand_spawn(
if (number == count)
clif_displaymessage(fd, msg_table[39]); // All monster summoned!
else {
- sprintf(output, msg_table[240], count); // %d monster(s) summoned!
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[240], count); // %d monster(s) summoned!
+ clif_displaymessage(fd, atcmd_output);
}
else {
clif_displaymessage(fd, msg_table[40]); // Invalid monster ID or name.
@@ -3254,6 +3443,8 @@ void atcommand_killmonster_sub(
int map_id;
char map_name[100];
+ if (!sd) return;
+
memset(map_name, '\0', sizeof(map_name));
if (!message || !*message || sscanf(message, "%99s", map_name) < 1)
@@ -3280,6 +3471,7 @@ int atcommand_killmonster(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ if (!sd) return 0;
atcommand_killmonster_sub(fd, sd, message, 1);
return 0;
@@ -3293,6 +3485,7 @@ int atcommand_killmonster2(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ if (!sd) return 0;
atcommand_killmonster_sub(fd, sd, message, 0);
return 0;
@@ -3308,9 +3501,9 @@ int atcommand_refine(
{
int i, position = 0, refine = 0, current_position, final_refine;
int count;
- char output[200];
+ nullpo_retr(-1, sd);
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message || sscanf(message, "%d %d", &position, &refine) < 2) {
clif_displaymessage(fd, "Please, enter a position and a amount (usage: @refine <equip position> <+/- amount>).");
@@ -3337,7 +3530,7 @@ int atcommand_refine(
if (sd->status.inventory[i].refine != final_refine) {
sd->status.inventory[i].refine = final_refine;
current_position = sd->status.inventory[i].equip;
- pc_unequipitem(sd, i, 0, BF_NORMAL);
+ pc_unequipitem(sd, i, 3);
clif_refine(fd, sd, 0, i, sd->status.inventory[i].refine);
clif_delitem(sd, i, 1);
clif_additem(sd, i, 1, 0);
@@ -3353,8 +3546,8 @@ int atcommand_refine(
else if (count == 1)
clif_displaymessage(fd, msg_table[167]); // 1 item has been refined!
else {
- sprintf(output, msg_table[168], count); // %d items have been refined!
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[168], count); // %d items have been refined!
+ clif_displaymessage(fd, atcmd_output);
}
return 0;
@@ -3373,9 +3566,9 @@ int atcommand_produce(
int flag = 0;
struct item_data *item_data;
struct item tmp_item;
- char output[200];
+ nullpo_retr(-1, sd);
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
memset(item_name, '\0', sizeof(item_name));
if (!message || !*message || sscanf(message, "%99s %d %d", item_name, &attribute, &star) < 1) {
@@ -3412,10 +3605,10 @@ int atcommand_produce(
if (battle_config.error_log)
printf("@produce NOT WEAPON [%d]\n", item_id);
if (item_id != 0 && itemdb_exists(item_id))
- sprintf(output, msg_table[169], item_id, item_data->name); // This item (%d: '%s') is not an equipment.
+ sprintf(atcmd_output, msg_table[169], item_id, item_data->name); // This item (%d: '%s') is not an equipment.
else
- sprintf(output, msg_table[170]); // This item is not an equipment.
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[170]); // This item is not an equipment.
+ clif_displaymessage(fd, atcmd_output);
return -1;
}
@@ -3428,17 +3621,18 @@ int atcommand_produce(
*/
void atcommand_memo_sub(struct map_session_data* sd) {
int i;
- char output[200];
- memset(output, '\0', sizeof(output));
+ if (!sd) return;
+
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
clif_displaymessage(sd->fd, "Your actual memo positions are (except respawn point):");
for (i = MIN_PORTAL_MEMO; i <= MAX_PORTAL_MEMO; i++) {
if (sd->status.memo_point[i].map[0])
- sprintf(output, "%d - %s (%d,%d)", i, sd->status.memo_point[i].map, sd->status.memo_point[i].x, sd->status.memo_point[i].y);
+ sprintf(atcmd_output, "%d - %s (%d,%d)", i, sd->status.memo_point[i].map, sd->status.memo_point[i].x, sd->status.memo_point[i].y);
else
- sprintf(output, msg_table[171], i); // %d - void
- clif_displaymessage(sd->fd, output);
+ sprintf(atcmd_output, msg_table[171], i); // %d - void
+ clif_displaymessage(sd->fd, atcmd_output);
}
return;
@@ -3453,21 +3647,21 @@ int atcommand_memo(
const char* command, const char* message)
{
int position = 0;
- char output[200];
+ nullpo_retr(-1, sd);
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message || sscanf(message, "%d", &position) < 1)
atcommand_memo_sub(sd);
else {
if (position >= MIN_PORTAL_MEMO && position <= MAX_PORTAL_MEMO) {
if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
- clif_displaymessage(fd, "You are not authorised to memo this map.");
+ clif_displaymessage(fd, msg_table[253]);
return -1;
}
if (sd->status.memo_point[position].map[0]) {
- sprintf(output, msg_table[172], position, sd->status.memo_point[position].map, sd->status.memo_point[position].x, sd->status.memo_point[position].y); // You replace previous memo position %d - %s (%d,%d).
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[172], position, sd->status.memo_point[position].map, sd->status.memo_point[position].x, sd->status.memo_point[position].y); // You replace previous memo position %d - %s (%d,%d).
+ clif_displaymessage(fd, atcmd_output);
}
memcpy(sd->status.memo_point[position].map, map[sd->bl.m].name, 24);
sd->status.memo_point[position].x = sd->bl.x;
@@ -3477,8 +3671,8 @@ int atcommand_memo(
clif_displaymessage(fd, msg_table[173]); // Note: you don't have the 'Warp' skill level to use it.
atcommand_memo_sub(sd);
} else {
- sprintf(output, "Please, enter a valid position (usage: @memo <memo_position:%d-%d>).", MIN_PORTAL_MEMO, MAX_PORTAL_MEMO);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Please, enter a valid position (usage: @memo <memo_position:%d-%d>).", MIN_PORTAL_MEMO, MAX_PORTAL_MEMO);
+ clif_displaymessage(fd, atcmd_output);
atcommand_memo_sub(sd);
return -1;
}
@@ -3495,20 +3689,21 @@ int atcommand_gat(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char output[200];
int y;
+ nullpo_retr(-1, sd);
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
for (y = 2; y >= -2; y--) {
- sprintf(output, "%s (x= %d, y= %d) %02X %02X %02X %02X %02X",
- map[sd->bl.m].name, sd->bl.x - 2, sd->bl.y + y,
- map_getcell(sd->bl.m, sd->bl.x - 2, sd->bl.y + y),
- map_getcell(sd->bl.m, sd->bl.x - 1, sd->bl.y + y),
- map_getcell(sd->bl.m, sd->bl.x, sd->bl.y + y),
- map_getcell(sd->bl.m, sd->bl.x + 1, sd->bl.y + y),
- map_getcell(sd->bl.m, sd->bl.x + 2, sd->bl.y + y));
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "%s (x= %d, y= %d) %02X %02X %02X %02X %02X",
+ map[sd->bl.m].name, sd->bl.x - 2, sd->bl.y + y,
+ map_getcell(sd->bl.m, sd->bl.x - 2, sd->bl.y + y, CELL_GETTYPE),
+ map_getcell(sd->bl.m, sd->bl.x - 1, sd->bl.y + y, CELL_GETTYPE),
+ map_getcell(sd->bl.m, sd->bl.x, sd->bl.y + y, CELL_GETTYPE),
+ map_getcell(sd->bl.m, sd->bl.x + 1, sd->bl.y + y, CELL_GETTYPE),
+ map_getcell(sd->bl.m, sd->bl.x + 2, sd->bl.y + y, CELL_GETTYPE));
+
+ clif_displaymessage(fd, atcmd_output);
}
return 0;
@@ -3523,6 +3718,7 @@ int atcommand_packet(
const char* command, const char* message)
{
int x = 0, y = 0;
+ nullpo_retr(-1, sd);
if (!message || !*message || sscanf(message, "%d %d", &x, &y) < 2) {
clif_displaymessage(fd, "Please, enter a status type/flag (usage: @packet <status type> <flag>).");
@@ -3579,6 +3775,7 @@ int atcommand_skillpoint(
const char* command, const char* message)
{
int point, new_skill_point;
+ nullpo_retr(-1, sd);
if (!message || !*message || (point = atoi(message)) == 0) {
clif_displaymessage(fd, "Please, enter a number (usage: @skpoint <number of points>).");
@@ -3615,6 +3812,7 @@ int atcommand_zeny(
const char* command, const char* message)
{
int zeny, new_zeny;
+ nullpo_retr(-1, sd);
if (!message || !*message || (zeny = atoi(message)) == 0) {
clif_displaymessage(fd, "Please, enter an amount (usage: @zeny <amount>).");
@@ -3656,13 +3854,13 @@ int atcommand_param(
&sd->status.str, &sd->status.agi, &sd->status.vit,
&sd->status.int_, &sd->status.dex, &sd->status.luk
};
- char output[200];
+ nullpo_retr(-1, sd);
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message || sscanf(message, "%d", &value) < 1 || value == 0) {
- sprintf(output, "Please, enter a valid value (usage: @str,@agi,@vit,@int,@dex,@luk <+/-adjustement>).");
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Please, enter a valid value (usage: @str,@agi,@vit,@int,@dex,@luk <+/-adjustement>).");
+ clif_displaymessage(fd, atcmd_output);
return -1;
}
@@ -3674,22 +3872,22 @@ int atcommand_param(
}
}
if (index < 0 || index > MAX_STATUS_TYPE) { // normaly impossible...
- sprintf(output, "Please, enter a valid value (usage: @str,@agi,@vit,@int,@dex,@luk <+/-adjustement>).");
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Please, enter a valid value (usage: @str,@agi,@vit,@int,@dex,@luk <+/-adjustement>).");
+ clif_displaymessage(fd, atcmd_output);
return -1;
}
new_value = (int)*status[index] + value;
- if (value > 0 && (value > battle_config.max_parameter || new_value > battle_config.max_parameter)) // fix positiv overflow
+ if (value > 0 && ((unsigned int)value > battle_config.max_parameter || (unsigned int)new_value > battle_config.max_parameter)) // fix positiv overflow
new_value = battle_config.max_parameter;
- else if (value < 0 && (value < -battle_config.max_parameter || new_value < 1)) // fix negativ overflow
+ else if (value < 0 && (value < -(int)battle_config.max_parameter || new_value < 1)) // fix negativ overflow
new_value = 1;
if (new_value != (int)*status[index]) {
*status[index] = new_value;
clif_updatestatus(sd, SP_STR + index);
clif_updatestatus(sd, SP_USTR + index);
- pc_calcstatus(sd, 0);
+ status_calc_pc(sd, 0);
clif_displaymessage(fd, msg_table[42]); // Stat changed.
} else {
if (value < 0)
@@ -3716,6 +3914,7 @@ int atcommand_stat_all(
&sd->status.str, &sd->status.agi, &sd->status.vit,
&sd->status.int_, &sd->status.dex, &sd->status.luk
};
+ nullpo_retr(-1, sd);
if (!message || !*message || sscanf(message, "%d", &value) < 1 || value == 0)
value = battle_config.max_parameter;
@@ -3724,16 +3923,16 @@ int atcommand_stat_all(
for (index = 0; index < (int)(sizeof(status) / sizeof(status[0])); index++) {
new_value = (int)*status[index] + value;
- if (value > 0 && (value > battle_config.max_parameter || new_value > battle_config.max_parameter)) // fix positiv overflow
+ if (value > 0 && ((unsigned int)value > battle_config.max_parameter || (unsigned int)new_value > battle_config.max_parameter)) // fix positiv overflow
new_value = battle_config.max_parameter;
- else if (value < 0 && (value < -battle_config.max_parameter || new_value < 1)) // fix negativ overflow
+ else if (value < 0 && (value < -(int)battle_config.max_parameter || new_value < 1)) // fix negativ overflow
new_value = 1;
if (new_value != (int)*status[index]) {
*status[index] = new_value;
clif_updatestatus(sd, SP_STR + index);
clif_updatestatus(sd, SP_USTR + index);
- pc_calcstatus(sd, 0);
+ status_calc_pc(sd, 0);
count++;
}
}
@@ -3762,6 +3961,7 @@ int atcommand_guildlevelup(
int level = 0;
short added_level;
struct guild *guild_info;
+ nullpo_retr(-1, sd);
if (!message || !*message || sscanf(message, "%d", &level) < 1 || level == 0) {
clif_displaymessage(fd, "Please, enter a valid level (usage: @guildlvup/@guildlvlup <# of levels>).");
@@ -3804,6 +4004,7 @@ int atcommand_makeegg(
{
struct item_data *item_data;
int id, pet_id;
+ nullpo_retr(-1, sd);
if (!message || !*message) {
clif_displaymessage(fd, "Please, enter a monter/egg name/id (usage: @makeegg <pet_id>).");
@@ -3819,11 +4020,11 @@ int atcommand_makeegg(
if (pet_id < 0)
pet_id = search_petDB_index(id, PET_EGG);
if (pet_id >= 0) {
- sd->catch_target_class = pet_db[pet_id].class;
+ sd->catch_target_class = pet_db[pet_id].class_;
intif_create_pet(
sd->status.account_id, sd->status.char_id,
- pet_db[pet_id].class, mob_db[pet_db[pet_id].class].lv,
- pet_db[pet_id].EggID, 0, pet_db[pet_id].intimate,
+ (short)pet_db[pet_id].class_, (short)mob_db[pet_db[pet_id].class_].lv,
+ (short)pet_db[pet_id].EggID, 0, (short)pet_db[pet_id].intimate,
100, 0, 1, pet_db[pet_id].jname);
} else {
clif_displaymessage(fd, msg_table[180]); // The monter/egg name/id doesn't exist.
@@ -3841,6 +4042,7 @@ int atcommand_hatch(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
if (sd->status.pet_id <= 0)
clif_sendegg(sd);
else {
@@ -3861,6 +4063,7 @@ int atcommand_petfriendly(
{
int friendly;
int t;
+ nullpo_retr(-1, sd);
if (!message || !*message || (friendly = atoi(message)) < 0) {
clif_displaymessage(fd, "Please, enter a valid value (usage: @petfriendly <0-1000>).");
@@ -3877,9 +4080,9 @@ int atcommand_petfriendly(
if ((sd->pet.intimate > 0 && t <= 0) ||
(sd->pet.intimate <= 0 && t > 0)) {
if (sd->bl.prev != NULL)
- pc_calcstatus(sd, 0);
+ status_calc_pc(sd, 0);
else
- pc_calcstatus(sd, 2);
+ status_calc_pc(sd, 2);
}
}
clif_displaymessage(fd, msg_table[182]); // Pet friendly value changed!
@@ -3908,6 +4111,7 @@ int atcommand_pethungry(
const char* command, const char* message)
{
int hungry;
+ nullpo_retr(-1, sd);
if (!message || !*message || (hungry = atoi(message)) < 0) {
clif_displaymessage(fd, "Please, enter a valid number (usage: @pethungry <0-100>).");
@@ -3944,6 +4148,7 @@ int atcommand_petrename(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
if (sd->status.pet_id > 0 && sd->pd) {
if (sd->pet.rename_flag != 0) {
sd->pet.rename_flag = 0;
@@ -3971,24 +4176,22 @@ atcommand_recall(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
- char output[200];
struct map_session_data *pl_sd = NULL;
-
+
nullpo_retr(-1, sd);
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
clif_displaymessage(fd, "Please, enter a player name (usage: @recall <char name>).");
return -1;
}
-
- memset(character, '\0', sizeof character);
- if(sscanf(message, "%99[^\n]", character) < 1)
+
+ memset(atcmd_player_name, '\0', sizeof atcmd_player_name);
+ if(sscanf(message, "%99[^\n]", atcmd_player_name) < 1)
return -1;
- if(strncmp(sd->status.name,character,24)==0)
+ if(strncmp(sd->status.name,atcmd_player_name,24)==0)
return -1;
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can recall only lower or same level
if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
clif_displaymessage(fd, "You are not authorised to warp somenone to your actual map.");
@@ -3999,8 +4202,8 @@ atcommand_recall(
return -1;
}
pc_setpos(pl_sd, sd->mapname, sd->bl.x, sd->bl.y, 2);
- sprintf(output, msg_table[46], character); // %s recalled!
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[46], atcmd_player_name); // %s recalled!
+ clif_displaymessage(fd, atcmd_output);
} else {
clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
return -1;
@@ -4021,23 +4224,23 @@ int atcommand_revive(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
struct map_session_data *pl_sd;
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
clif_displaymessage(fd, "Please, enter a player name (usage: @revive <char name>).");
return -1;
}
- if ((pl_sd = map_nick2sd(character)) != NULL) {
- if (pc_isdead(sd)) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
+ if (pc_isdead(pl_sd)) {
pl_sd->status.hp = pl_sd->status.max_hp;
clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1);
pc_setstand(pl_sd);
if (battle_config.pc_invincible_time > 0)
- pc_setinvincibletimer(sd, battle_config.pc_invincible_time);
+ pc_setinvincibletimer(pl_sd, battle_config.pc_invincible_time);
clif_updatestatus(pl_sd, SP_HP);
clif_updatestatus(pl_sd, SP_SP);
clif_resurrection(&pl_sd->bl, 1);
@@ -4061,24 +4264,24 @@ int atcommand_char_change_sex(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
clif_displaymessage(fd, "Please, enter a player name (usage: @charchangesex <name>).");
return -1;
}
// check player name
- if (strlen(character) < 4) {
+ if (strlen(atcmd_player_name) < 4) {
clif_displaymessage(fd, msg_table[86]); // Sorry, but a player name have at least 4 characters.
return -1;
- } else if (strlen(character) > 23) {
+ } else if (strlen(atcmd_player_name) > 23) {
clif_displaymessage(fd, msg_table[87]); // Sorry, but a player name have 23 characters maximum.
return -1;
} else {
- chrif_char_ask_name(sd->status.account_id, character, 5, 0, 0, 0, 0, 0, 0); // type: 5 - changesex
+ chrif_char_ask_name(sd->status.account_id, atcmd_player_name, 5, 0, 0, 0, 0, 0, 0); // type: 5 - changesex
clif_displaymessage(fd, msg_table[88]); // Character name sends to char-server to ask it.
}
@@ -4094,24 +4297,24 @@ int atcommand_char_block(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
clif_displaymessage(fd, "Please, enter a player name (usage: @charblock/@block <name>).");
return -1;
}
// check player name
- if (strlen(character) < 4) {
+ if (strlen(atcmd_player_name) < 4) {
clif_displaymessage(fd, msg_table[86]); // Sorry, but a player name have at least 4 characters.
return -1;
- } else if (strlen(character) > 23) {
+ } else if (strlen(atcmd_player_name) > 23) {
clif_displaymessage(fd, msg_table[87]); // Sorry, but a player name have 23 characters maximum.
return -1;
} else {
- chrif_char_ask_name(sd->status.account_id, character, 1, 0, 0, 0, 0, 0, 0); // type: 1 - block
+ chrif_char_ask_name(sd->status.account_id, atcmd_player_name, 1, 0, 0, 0, 0, 0, 0); // type: 1 - block
clif_displaymessage(fd, msg_table[88]); // Character name sends to char-server to ask it.
}
@@ -4138,22 +4341,21 @@ int atcommand_char_ban(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char modif[100], character[100];
char * modif_p;
int year, month, day, hour, minute, second, value;
+ nullpo_retr(-1, sd);
- memset(modif, '\0', sizeof(modif));
- memset(character, '\0', sizeof(character));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%s %99[^\n]", modif, character) < 2) {
+ if (!message || !*message || sscanf(message, "%s %99[^\n]", atcmd_output, atcmd_player_name) < 2) {
clif_displaymessage(fd, "Please, enter ban time and a player name (usage: @charban/@ban/@banish/@charbanish <time> <name>).");
return -1;
}
- modif[sizeof(modif)-1] = '\0';
- character[sizeof(character)-1] = '\0';
+ atcmd_output[sizeof(atcmd_output)-1] = '\0';
- modif_p = modif;
+ modif_p = atcmd_output;
year = month = day = hour = minute = second = 0;
while (modif_p[0] != '\0') {
value = atoi(modif_p);
@@ -4193,14 +4395,14 @@ int atcommand_char_ban(
}
// check player name
- if (strlen(character) < 4) {
+ if (strlen(atcmd_player_name) < 4) {
clif_displaymessage(fd, msg_table[86]); // Sorry, but a player name have at least 4 characters.
return -1;
- } else if (strlen(character) > 23) {
+ } else if (strlen(atcmd_player_name) > 23) {
clif_displaymessage(fd, msg_table[87]); // Sorry, but a player name have 23 characters maximum.
return -1;
} else {
- chrif_char_ask_name(sd->status.account_id, character, 2, year, month, day, hour, minute, second); // type: 2 - ban
+ chrif_char_ask_name(sd->status.account_id, atcmd_player_name, 2, year, month, day, hour, minute, second); // type: 2 - ban
clif_displaymessage(fd, msg_table[88]); // Character name sends to char-server to ask it.
}
@@ -4215,25 +4417,25 @@ int atcommand_char_unblock(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
clif_displaymessage(fd, "Please, enter a player name (usage: @charunblock <player_name>).");
return -1;
}
// check player name
- if (strlen(character) < 4) {
+ if (strlen(atcmd_player_name) < 4) {
clif_displaymessage(fd, msg_table[86]); // Sorry, but a player name have at least 4 characters.
return -1;
- } else if (strlen(character) > 23) {
+ } else if (strlen(atcmd_player_name) > 23) {
clif_displaymessage(fd, msg_table[87]); // Sorry, but a player name have 23 characters maximum.
return -1;
} else {
// send answer to login server via char-server
- chrif_char_ask_name(sd->status.account_id, character, 3, 0, 0, 0, 0, 0, 0); // type: 3 - unblock
+ chrif_char_ask_name(sd->status.account_id, atcmd_player_name, 3, 0, 0, 0, 0, 0, 0); // type: 3 - unblock
clif_displaymessage(fd, msg_table[88]); // Character name sends to char-server to ask it.
}
@@ -4248,25 +4450,25 @@ int atcommand_char_unban(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
clif_displaymessage(fd, "Please, enter a player name (usage: @charunban <player_name>).");
return -1;
}
// check player name
- if (strlen(character) < 4) {
+ if (strlen(atcmd_player_name) < 4) {
clif_displaymessage(fd, msg_table[86]); // Sorry, but a player name have at least 4 characters.
return -1;
- } else if (strlen(character) > 23) {
+ } else if (strlen(atcmd_player_name) > 23) {
clif_displaymessage(fd, msg_table[87]); // Sorry, but a player name have 23 characters maximum.
return -1;
} else {
// send answer to login server via char-server
- chrif_char_ask_name(sd->status.account_id, character, 4, 0, 0, 0, 0, 0, 0); // type: 4 - unban
+ chrif_char_ask_name(sd->status.account_id, atcmd_player_name, 4, 0, 0, 0, 0, 0, 0); // type: 4 - unban
clif_displaymessage(fd, msg_table[88]); // Character name sends to char-server to ask it.
}
@@ -4283,11 +4485,12 @@ int atcommand_night(
{
struct map_session_data *pl_sd;
int i;
+ nullpo_retr(-1, sd);
if (night_flag != 1) {
night_flag = 1; // 0=day, 1=night [Yor]
for(i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth && !map[sd->bl.m].flag.indoors) {
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && !map[sd->bl.m].flag.indoors) {
//pl_sd->opt2 |= STATE_BLIND;
//clif_changeoption(&pl_sd->bl);
if (battle_config.night_darkness_level > 0)
@@ -4318,13 +4521,18 @@ int atcommand_day(
{
struct map_session_data *pl_sd;
int i;
+ nullpo_retr(-1, sd);
if (night_flag != 0) {
night_flag = 0; // 0=day, 1=night [Yor]
for(i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
- pl_sd->opt2 &= ~STATE_BLIND;
- clif_changeoption(&pl_sd->bl);
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) {
+ if (battle_config.night_darkness_level > 0)
+ clif_refresh (pl_sd);
+ else {
+ pl_sd->opt2 &= ~STATE_BLIND;
+ clif_changeoption(&pl_sd->bl);
+ }
clif_displaymessage(pl_sd->fd, msg_table[60]); // Day has arrived.
}
}
@@ -4346,9 +4554,10 @@ int atcommand_doom(
{
struct map_session_data *pl_sd;
int i;
+ nullpo_retr(-1, sd);
clif_specialeffect(&sd->bl,450,2);
for(i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth && i != fd &&
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && i != fd &&
pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can doom only lower or same gm level
pc_damage(NULL, pl_sd, pl_sd->status.hp + 1);
clif_displaymessage(pl_sd->fd, msg_table[61]); // The holy messenger has given judgement.
@@ -4369,9 +4578,10 @@ int atcommand_doommap(
{
struct map_session_data *pl_sd;
int i;
+ nullpo_retr(-1, sd);
clif_specialeffect(&sd->bl,450,3);
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth && i != fd && sd->bl.m == pl_sd->bl.m &&
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && i != fd && sd->bl.m == pl_sd->bl.m &&
pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can doom only lower or same gm level
pc_damage(NULL, pl_sd, pl_sd->status.hp + 1);
// clif_specialeffect(&pl_sd->bl,450,1);
@@ -4412,10 +4622,11 @@ int atcommand_raise(
const char* command, const char* message)
{
int i;
+ nullpo_retr(-1, sd);
for (i = 0; i < fd_max; i++) {
if (session[i])
- atcommand_raise_sub(session[i]->session_data);
+ atcommand_raise_sub((struct map_session_data *) session[i]->session_data);
}
clif_displaymessage(fd, msg_table[64]); // Mercy has been granted.
@@ -4433,8 +4644,10 @@ int atcommand_raisemap(
struct map_session_data *pl_sd;
int i;
+ nullpo_retr(-1, sd);
+
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth && sd->bl.m == pl_sd->bl.m)
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && sd->bl.m == pl_sd->bl.m)
atcommand_raise_sub(pl_sd);
}
clif_displaymessage(fd, msg_table[64]); // Mercy has been granted.
@@ -4451,17 +4664,17 @@ int atcommand_character_baselevel(
const char* command, const char* message)
{
struct map_session_data *pl_sd;
- char character[100];
int level = 0, i;
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%d %99[^\n]", &level, character) < 2 || level == 0) {
+ if (!message || !*message || sscanf(message, "%d %99[^\n]", &level, atcmd_player_name) < 2 || level == 0) {
clif_displaymessage(fd, "Please, enter a level adjustement and a player name (usage: @charbaselvl <#> <nickname>).");
return -1;
}
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can change base level only lower or same gm level
if (level > 0) {
@@ -4469,7 +4682,7 @@ int atcommand_character_baselevel(
clif_displaymessage(fd, msg_table[91]); // Character's base level can't go any higher.
return 0;
} // End Addition
- if (level > battle_config.maximum_level || level > (battle_config.maximum_level - pl_sd->status.base_level)) // fix positiv overflow
+ if ((unsigned int)level > battle_config.maximum_level || (unsigned int)level > (battle_config.maximum_level - pl_sd->status.base_level)) // fix positiv overflow
level = battle_config.maximum_level - pl_sd->status.base_level;
for (i = 1; i <= level; i++)
pl_sd->status.status_point += (pl_sd->status.base_level + i + 14) / 5;
@@ -4477,7 +4690,7 @@ int atcommand_character_baselevel(
clif_updatestatus(pl_sd, SP_BASELEVEL);
clif_updatestatus(pl_sd, SP_NEXTBASEEXP);
clif_updatestatus(pl_sd, SP_STATUSPOINT);
- pc_calcstatus(pl_sd, 0);
+ status_calc_pc(pl_sd, 0);
pc_heal(pl_sd, pl_sd->status.max_hp, pl_sd->status.max_sp);
clif_misceffect(&pl_sd->bl, 0);
clif_displaymessage(fd, msg_table[65]); // Character's base level raised.
@@ -4486,7 +4699,7 @@ int atcommand_character_baselevel(
clif_displaymessage(fd, msg_table[193]); // Character's base level can't go any lower.
return -1;
}
- if (level < -battle_config.maximum_level || level < (1 - pl_sd->status.base_level)) // fix negativ overflow
+ if (level < -(int)battle_config.maximum_level || level < (1 - (int)pl_sd->status.base_level)) // fix negativ overflow
level = 1 - pl_sd->status.base_level;
if (pl_sd->status.status_point > 0) {
for (i = 0; i > level; i--)
@@ -4498,7 +4711,7 @@ int atcommand_character_baselevel(
pl_sd->status.base_level += level;
clif_updatestatus(pl_sd, SP_BASELEVEL);
clif_updatestatus(pl_sd, SP_NEXTBASEEXP);
- pc_calcstatus(pl_sd, 0);
+ status_calc_pc(pl_sd, 0);
clif_displaymessage(fd, msg_table[66]); // Character's base level lowered.
}
} else {
@@ -4522,25 +4735,28 @@ int atcommand_character_joblevel(
const char* command, const char* message)
{
struct map_session_data *pl_sd;
- char character[100];
- int max_level = 50, level = 0;
+ unsigned int max_level = 50;
+ int level = 0;
//“]¶‚â—{Žq‚Ìꇂ̌³‚ÌE‹Æ‚ðŽZo‚·‚é
struct pc_base_job pl_s_class;
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%d %99[^\n]", &level, character) < 2 || level == 0) {
+ if (!message || !*message || sscanf(message, "%d %99[^\n]", &level, atcmd_player_name) < 2 || level == 0) {
clif_displaymessage(fd, "Please, enter a level adjustement and a player name (usage: @charjlvl <#> <nickname>).");
return -1;
}
- if ((pl_sd = map_nick2sd(character)) != NULL) {
- pl_s_class = pc_calc_base_job(pl_sd->status.class);
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
+ pl_s_class = pc_calc_base_job(pl_sd->status.class_);
if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can change job level only lower or same gm level
if (pl_s_class.job == 0)
max_level -= 40;
- if ((pl_s_class.job == 23) || (pl_s_class.upper == 1 && pl_s_class.type == 2)) //ƒXƒpƒmƒr‚Æ“]¶E‚ÍJobƒŒƒxƒ‹‚ÌÅ‚‚ª70
- // To-do: super novices has max level 99 - celest
+ // super novices can go up to 99 [celest]
+ else if (pl_s_class.job == 23)
+ max_level += 49;
+ else if (pl_sd->status.class_ > 4007 && pl_sd->status.class_ < 4023)
max_level += 20;
if (level > 0) {
@@ -4555,7 +4771,7 @@ int atcommand_character_joblevel(
clif_updatestatus(pl_sd, SP_NEXTJOBEXP);
pl_sd->status.skill_point += level;
clif_updatestatus(pl_sd, SP_SKILLPOINT);
- pc_calcstatus(pl_sd, 0);
+ status_calc_pc(pl_sd, 0);
clif_misceffect(&pl_sd->bl, 1);
clif_displaymessage(fd, msg_table[68]); // character's job level raised.
} else {
@@ -4574,7 +4790,7 @@ int atcommand_character_joblevel(
pl_sd->status.skill_point = 0;
clif_updatestatus(pl_sd, SP_SKILLPOINT);
} // to add: remove status points from skills
- pc_calcstatus(pl_sd, 0);
+ status_calc_pc(pl_sd, 0);
clif_displaymessage(fd, msg_table[69]); // Character's job level lowered.
}
} else {
@@ -4598,16 +4814,16 @@ int atcommand_kick(
const char* command, const char* message)
{
struct map_session_data *pl_sd;
- char character[100];
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
clif_displaymessage(fd, "Please, enter a player name (usage: @kick <charname>).");
return -1;
}
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
if (pc_isGM(sd) >= pc_isGM(pl_sd)) // you can kick only lower or same gm level
clif_GM_kick(sd, pl_sd, 1);
else {
@@ -4632,9 +4848,10 @@ int atcommand_kickall(
{
struct map_session_data *pl_sd;
int i;
+ nullpo_retr(-1, sd);
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth &&
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth &&
pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can kick only lower or same gm level
if (sd->status.account_id != pl_sd->status.account_id)
clif_GM_kick(sd, pl_sd, 0);
@@ -4654,6 +4871,7 @@ int atcommand_allskill(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
pc_allskillup(sd); // all skills
sd->status.skill_point = 0; // 0 skill points
clif_updatestatus(sd, SP_SKILLPOINT); // update
@@ -4671,6 +4889,7 @@ int atcommand_questskill(
const char* command, const char* message)
{
int skill_id;
+ nullpo_retr(-1, sd);
if (!message || !*message || (skill_id = atoi(message)) < 0) {
clif_displaymessage(fd, "Please, enter a quest skill number (usage: @questskill <#:0+>).");
@@ -4706,20 +4925,20 @@ int atcommand_charquestskill(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
struct map_session_data *pl_sd;
int skill_id = 0;
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%d %99[^\n]", &skill_id, character) < 2 || skill_id < 0) {
+ if (!message || !*message || sscanf(message, "%d %99[^\n]", &skill_id, atcmd_player_name) < 2 || skill_id < 0) {
clif_displaymessage(fd, "Please, enter a quest skill number and a player name (usage: @charquestskill <#:0+> <char_name>).");
return -1;
}
if (skill_id >= 0 && skill_id < MAX_SKILL_DB) {
if (skill_get_inf2(skill_id) & 0x01) {
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
if (pc_checkskill(pl_sd, skill_id) == 0) {
pc_skill(pl_sd, skill_id, 1, 0);
clif_displaymessage(fd, msg_table[199]); // This player has learned the skill.
@@ -4752,6 +4971,7 @@ int atcommand_lostskill(
const char* command, const char* message)
{
int skill_id;
+ nullpo_retr(-1, sd);
if (!message || !*message || (skill_id = atoi(message)) < 0) {
clif_displaymessage(fd, "Please, enter a quest skill number (usage: @lostskill <#:0+>).");
@@ -4789,20 +5009,20 @@ int atcommand_charlostskill(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
struct map_session_data *pl_sd;
int skill_id = 0;
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%d %99[^\n]", &skill_id, character) < 2 || skill_id < 0) {
+ if (!message || !*message || sscanf(message, "%d %99[^\n]", &skill_id, atcmd_player_name) < 2 || skill_id < 0) {
clif_displaymessage(fd, "Please, enter a quest skill number and a player name (usage: @charlostskill <#:0+> <char_name>).");
return -1;
}
if (skill_id >= 0 && skill_id < MAX_SKILL) {
if (skill_get_inf2(skill_id) & 0x01) {
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
if (pc_checkskill(pl_sd, skill_id) > 0) {
pl_sd->status.skill[skill_id].lv = 0;
pl_sd->status.skill[skill_id].flag = 0;
@@ -4837,6 +5057,7 @@ int atcommand_spiritball(
const char* command, const char* message)
{
int number;
+ nullpo_retr(-1, sd);
if (!message || !*message || (number = atoi(message)) < 0) {
clif_displaymessage(fd, "Please, enter a spirit ball number (usage: @spiritball <number: 0-1000>).");
@@ -4877,6 +5098,7 @@ int atcommand_party(
const char* command, const char* message)
{
char party[100];
+ nullpo_retr(-1, sd);
memset(party, '\0', sizeof(party));
@@ -4885,7 +5107,7 @@ int atcommand_party(
return -1;
}
- party_create(sd, party);
+ party_create(sd, party, 0, 0);
return 0;
}
@@ -4900,6 +5122,7 @@ int atcommand_guild(
{
char guild[100];
int prev;
+ nullpo_retr(-1, sd);
memset(guild, '\0', sizeof(guild));
@@ -4924,6 +5147,7 @@ int atcommand_agitstart(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
if (agit_flag == 1) {
clif_displaymessage(fd, msg_table[73]); // Already it has started siege warfare.
return -1;
@@ -4944,6 +5168,7 @@ int atcommand_agitend(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
if (agit_flag == 0) {
clif_displaymessage(fd, msg_table[75]); // Siege warfare hasn't started yet.
return -1;
@@ -4966,14 +5191,17 @@ int atcommand_mapexit(
{
struct map_session_data *pl_sd;
int i;
+ nullpo_retr(-1, sd);
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) {
if (sd->status.account_id != pl_sd->status.account_id)
clif_GM_kick(sd, pl_sd, 0);
}
}
clif_GM_kick(sd, sd, 0);
+
+ flush_fifos();
runflag = 0;
@@ -4989,30 +5217,30 @@ int atcommand_idsearch(
const char* command, const char* message)
{
char item_name[100];
- char output[200];
- int i, match;
+ unsigned int i, match;
struct item_data *item;
+ nullpo_retr(-1, sd);
memset(item_name, '\0', sizeof(item_name));
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message || sscanf(message, "%99s", item_name) < 0) {
clif_displaymessage(fd, "Please, enter a part of item name (usage: @idsearch <part_of_item_name>).");
return -1;
}
- sprintf(output, msg_table[77], item_name); // The reference result of '%s' (name: id):
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[77], item_name); // The reference result of '%s' (name: id):
+ clif_displaymessage(fd, atcmd_output);
match = 0;
for(i = 0; i < 20000; i++) {
if ((item = itemdb_exists(i)) != NULL && strstr(item->jname, item_name) != NULL) {
match++;
- sprintf(output, msg_table[78], item->jname, item->nameid); // %s: %d
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[78], item->jname, item->nameid); // %s: %d
+ clif_displaymessage(fd, atcmd_output);
}
}
- sprintf(output, msg_table[79], match); // It is %d affair above.
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[79], match); // It is %d affair above.
+ clif_displaymessage(fd, atcmd_output);
return 0;
}
@@ -5025,23 +5253,22 @@ int atcommand_charskreset(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
- char output[200];
struct map_session_data *pl_sd;
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
- memset(output, '\0', sizeof(output));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
clif_displaymessage(fd, "Please, enter a player name (usage: @charskreset <charname>).");
return -1;
}
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can reset skill points only lower or same gm level
pc_resetskill(pl_sd);
- sprintf(output, msg_table[206], character); // '%s' skill points reseted!
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[206], atcmd_player_name); // '%s' skill points reseted!
+ clif_displaymessage(fd, atcmd_output);
} else {
clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
return -1;
@@ -5062,23 +5289,22 @@ int atcommand_charstreset(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
- char output[200];
struct map_session_data *pl_sd;
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
- memset(output, '\0', sizeof(output));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
clif_displaymessage(fd, "Please, enter a player name (usage: @charstreset <charname>).");
return -1;
}
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can reset stats points only lower or same gm level
pc_resetstate(pl_sd);
- sprintf(output, msg_table[207], character); // '%s' stats points reseted!
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[207], atcmd_player_name); // '%s' stats points reseted!
+ clif_displaymessage(fd, atcmd_output);
} else {
clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
return -1;
@@ -5101,27 +5327,26 @@ int atcommand_charmodel(
{
int hair_style = 0, hair_color = 0, cloth_color = 0;
struct map_session_data *pl_sd;
- char character[100];
- char output[200];
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
- memset(output, '\0', sizeof(output));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
- if (!message || !*message || sscanf(message, "%d %d %d %99[^\n]", &hair_style, &hair_color, &cloth_color, character) < 4 || hair_style < 0 || hair_color < 0 || cloth_color < 0) {
- sprintf(output, "Please, enter a valid model and a player name (usage: @charmodel <hair ID: %d-%d> <hair color: %d-%d> <clothes color: %d-%d> <name>).",
+ if (!message || !*message || sscanf(message, "%d %d %d %99[^\n]", &hair_style, &hair_color, &cloth_color, atcmd_player_name) < 4 || hair_style < 0 || hair_color < 0 || cloth_color < 0) {
+ sprintf(atcmd_output, "Please, enter a valid model and a player name (usage: @charmodel <hair ID: %d-%d> <hair color: %d-%d> <clothes color: %d-%d> <name>).",
MIN_HAIR_STYLE, MAX_HAIR_STYLE, MIN_HAIR_COLOR, MAX_HAIR_COLOR, MIN_CLOTH_COLOR, MAX_CLOTH_COLOR);
- clif_displaymessage(fd, output);
+ clif_displaymessage(fd, atcmd_output);
return -1;
}
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
if (hair_style >= MIN_HAIR_STYLE && hair_style <= MAX_HAIR_STYLE &&
hair_color >= MIN_HAIR_COLOR && hair_color <= MAX_HAIR_COLOR &&
cloth_color >= MIN_CLOTH_COLOR && cloth_color <= MAX_CLOTH_COLOR) {
if (cloth_color != 0 &&
pl_sd->status.sex == 1 &&
- (pl_sd->status.class == 12 || pl_sd->status.class == 17)) {
+ (pl_sd->status.class_ == 12 || pl_sd->status.class_ == 17)) {
clif_displaymessage(fd, msg_table[35]); // You can't use this command with this class.
return -1;
} else {
@@ -5151,18 +5376,18 @@ int atcommand_charskpoint(
const char* command, const char* message)
{
struct map_session_data *pl_sd;
- char character[100];
int new_skill_point;
int point = 0;
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%d %99[^\n]", &point, character) < 2 || point == 0) {
+ if (!message || !*message || sscanf(message, "%d %99[^\n]", &point, atcmd_player_name) < 2 || point == 0) {
clif_displaymessage(fd, "Please, enter a number and a player name (usage: @charskpoint <amount> <name>).");
return -1;
}
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
new_skill_point = (int)pl_sd->status.skill_point + point;
if (point > 0 && (point > 0x7FFF || new_skill_point > 0x7FFF)) // fix positiv overflow
new_skill_point = 0x7FFF;
@@ -5196,18 +5421,18 @@ int atcommand_charstpoint(
const char* command, const char* message)
{
struct map_session_data *pl_sd;
- char character[100];
int new_status_point;
int point = 0;
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%d %99[^\n]", &point, character) < 2 || point == 0) {
+ if (!message || !*message || sscanf(message, "%d %99[^\n]", &point, atcmd_player_name) < 2 || point == 0) {
clif_displaymessage(fd, "Please, enter a number and a player name (usage: @charstpoint <amount> <name>).");
return -1;
}
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
new_status_point = (int)pl_sd->status.status_point + point;
if (point > 0 && (point > 0x7FFF || new_status_point > 0x7FFF)) // fix positiv overflow
new_status_point = 0x7FFF;
@@ -5233,50 +5458,6 @@ int atcommand_charstpoint(
}
/*==========================================
- * Character Zeny Point (Rewritten by [Yor])
- *------------------------------------------
- */
-int atcommand_charzeny(
- const int fd, struct map_session_data* sd,
- const char* command, const char* message)
-{
- struct map_session_data *pl_sd;
- char character[100];
- int zeny = 0, new_zeny;
-
- memset(character, '\0', sizeof(character));
-
- if (!message || !*message || sscanf(message, "%d %99[^\n]", &zeny, character) < 2 || zeny == 0) {
- clif_displaymessage(fd, "Please, enter a number and a player name (usage: @charzeny <zeny> <name>).");
- return -1;
- }
-
- if ((pl_sd = map_nick2sd(character)) != NULL) {
- new_zeny = pl_sd->status.zeny + zeny;
- if (zeny > 0 && (zeny > MAX_ZENY || new_zeny > MAX_ZENY)) // fix positiv overflow
- new_zeny = MAX_ZENY;
- else if (zeny < 0 && (zeny < -MAX_ZENY || new_zeny < 0)) // fix negativ overflow
- new_zeny = 0;
- if (new_zeny != pl_sd->status.zeny) {
- pl_sd->status.zeny = new_zeny;
- clif_updatestatus(pl_sd, SP_ZENY);
- clif_displaymessage(fd, msg_table[211]); // Character's number of zenys changed!
- } else {
- if (zeny < 0)
- clif_displaymessage(fd, msg_table[41]); // Impossible to decrease the number/value.
- else
- clif_displaymessage(fd, msg_table[149]); // Impossible to increase the number/value.
- return -1;
- }
- } else {
- clif_displaymessage(fd, msg_table[3]); // Character not found.
- return -1;
- }
-
- return 0;
-}
-
-/*==========================================
* Recall All Characters Online To Your Location
*------------------------------------------
*/
@@ -5287,9 +5468,9 @@ int atcommand_recallall(
struct map_session_data *pl_sd;
int i;
int count;
- char output[200];
+ nullpo_retr(-1, sd);
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
clif_displaymessage(fd, "You are not authorised to warp somenone to your actual map.");
@@ -5298,7 +5479,7 @@ int atcommand_recallall(
count = 0;
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth && sd->status.account_id != pl_sd->status.account_id &&
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && sd->status.account_id != pl_sd->status.account_id &&
pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can recall only lower or same level
if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd))
count++;
@@ -5309,8 +5490,8 @@ int atcommand_recallall(
clif_displaymessage(fd, msg_table[92]); // All characters recalled!
if (count) {
- sprintf(output, "Because you are not authorised to warp from some maps, %d player(s) have not been recalled.", count);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Because you are not authorised to warp from some maps, %d player(s) have not been recalled.", count);
+ clif_displaymessage(fd, atcmd_output);
}
return 0;
@@ -5327,12 +5508,12 @@ int atcommand_guildrecall(
struct map_session_data *pl_sd;
int i;
char guild_name[100];
- char output[200];
struct guild *g;
int count;
+ nullpo_retr(-1, sd);
memset(guild_name, '\0', sizeof(guild_name));
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message || sscanf(message, "%99[^\n]", guild_name) < 1) {
clif_displaymessage(fd, "Please, enter a guild name/id (usage: @guildrecall <guild_name/id>).");
@@ -5348,7 +5529,7 @@ int atcommand_guildrecall(
(g = guild_search(atoi(message))) != NULL) {
count = 0;
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth &&
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth &&
sd->status.account_id != pl_sd->status.account_id &&
pl_sd->status.guild_id == g->guild_id) {
if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd))
@@ -5357,11 +5538,11 @@ int atcommand_guildrecall(
pc_setpos(pl_sd, sd->mapname, sd->bl.x, sd->bl.y, 2);
}
}
- sprintf(output, msg_table[93], g->name); // All online characters of the %s guild are near you.
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[93], g->name); // All online characters of the %s guild are near you.
+ clif_displaymessage(fd, atcmd_output);
if (count) {
- sprintf(output, "Because you are not authorised to warp from some maps, %d player(s) have not been recalled.", count);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Because you are not authorised to warp from some maps, %d player(s) have not been recalled.", count);
+ clif_displaymessage(fd, atcmd_output);
}
} else {
clif_displaymessage(fd, msg_table[94]); // Incorrect name/ID, or no one from the guild is online.
@@ -5382,12 +5563,12 @@ int atcommand_partyrecall(
int i;
struct map_session_data *pl_sd;
char party_name[100];
- char output[200];
struct party *p;
int count;
+ nullpo_retr(-1, sd);
memset(party_name, '\0', sizeof(party_name));
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message || sscanf(message, "%99[^\n]", party_name) < 1) {
clif_displaymessage(fd, "Please, enter a party name/id (usage: @partyrecall <party_name/id>).");
@@ -5403,7 +5584,7 @@ int atcommand_partyrecall(
(p = party_search(atoi(message))) != NULL) {
count = 0;
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth &&
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth &&
sd->status.account_id != pl_sd->status.account_id &&
pl_sd->status.party_id == p->party_id) {
if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd))
@@ -5412,11 +5593,11 @@ int atcommand_partyrecall(
pc_setpos(pl_sd, sd->mapname, sd->bl.x, sd->bl.y, 2);
}
}
- sprintf(output, msg_table[95], p->name); // All online characters of the %s party are near you.
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[95], p->name); // All online characters of the %s party are near you.
+ clif_displaymessage(fd, atcmd_output);
if (count) {
- sprintf(output, "Because you are not authorised to warp from some maps, %d player(s) have not been recalled.", count);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Because you are not authorised to warp from some maps, %d player(s) have not been recalled.", count);
+ clif_displaymessage(fd, atcmd_output);
}
} else {
clif_displaymessage(fd, msg_table[96]); // Incorrect name or ID, or no one from the party is online.
@@ -5434,6 +5615,7 @@ int atcommand_reloaditemdb(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
itemdb_reload();
clif_displaymessage(fd, msg_table[97]); // Item database reloaded.
@@ -5448,7 +5630,9 @@ int atcommand_reloadmobdb(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
mob_reload();
+ read_petdb();
clif_displaymessage(fd, msg_table[98]); // Monster database reloaded.
return 0;
@@ -5462,6 +5646,7 @@ int atcommand_reloadskilldb(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
skill_reload();
clif_displaymessage(fd, msg_table[99]); // Skill database reloaded.
@@ -5469,28 +5654,92 @@ int atcommand_reloadskilldb(
}
/*==========================================
+ * @reloadatcommand
+ * atcommand_athena.conf ‚ÌƒŠƒ[ƒh
+ *------------------------------------------
+ */
+int
+atcommand_reloadatcommand(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ atcommand_config_read(ATCOMMAND_CONF_FILENAME);
+ clif_displaymessage(fd, msg_table[254]);
+ return 0;
+}
+/*==========================================
+ * @reloadbattleconf
+ * battle_athena.conf ‚ÌƒŠƒ[ƒh
+ *------------------------------------------
+ */
+int
+atcommand_reloadbattleconf(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ battle_config_read(BATTLE_CONF_FILENAME);
+ clif_displaymessage(fd, msg_table[255]);
+ return 0;
+}
+/*==========================================
+ * @reloadstatusdb
+ * job_db1.txt job_db2.txt job_db2-2.txt
+ * refine_db.txt size_fix.txt
+ * ‚ÌƒŠƒ[ƒh
+ *------------------------------------------
+ */
+int
+atcommand_reloadstatusdb(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ status_readdb();
+ clif_displaymessage(fd, msg_table[256]);
+ return 0;
+}
+/*==========================================
+ * @reloadpcdb
+ * exp.txt skill_tree.txt attr_fix.txt
+ * ‚ÌƒŠƒ[ƒh
+ *------------------------------------------
+ */
+int
+atcommand_reloadpcdb(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ pc_readdb();
+ clif_displaymessage(fd, msg_table[257]);
+ return 0;
+}
+
+/*==========================================
*
*------------------------------------------
*/
-#ifndef TXT_ONLY
-int atcommand_rehash(
-#else /* TXT_ONLY */
+void rehash(void)
+{
+ int map_id;
+
+ for (map_id = 0; map_id < map_num; map_id++) {
+ map_foreachinarea(cleanup_sub, map_id, 0, 0, map[map_id].xs, map[map_id].ys, BL_MOB);
+ map_foreachinarea(cleanup_sub, map_id, 0, 0, map[map_id].xs, map[map_id].ys, BL_NPC);
+ }
+}
int atcommand_reloadscript(
-#endif /* TXT_ONLY */
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
-#ifndef TXT_ONLY
- atcommand_broadcast( fd, sd, "@broadcast", "eAthena SQL Server is Rehashing..." );
+ nullpo_retr(-1, sd);
+ atcommand_broadcast( fd, sd, "@broadcast", "eAthena Server is Rehashing..." );
atcommand_broadcast( fd, sd, "@broadcast", "You will feel a bit of lag at this point !" );
-
- rehash( fd, sd );
+
+ rehash();
atcommand_broadcast( fd, sd, "@broadcast", "Reloading NPCs..." );
-#endif /* not TXT_ONLY */
- do_init_npc();
+ //do_init_npc();
do_init_script();
-
+ npc_reload();
npc_event_do_oninit();
clif_displaymessage(fd, msg_table[100]); // Scripts reloaded.
@@ -5506,6 +5755,7 @@ int atcommand_reloadgmdb( // by [Yor]
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
chrif_reloadGMdb();
clif_displaymessage(fd, msg_table[101]); // Login-server asked to reload GM accounts and their level.
@@ -5529,71 +5779,71 @@ int atcommand_mapinfo(
struct map_session_data *pl_sd;
struct npc_data *nd = NULL;
struct chat_data *cd = NULL;
- char output[200], map_name[100];
char direction[12];
int m_id, i, chat_num, list = 0;
+ nullpo_retr(-1, sd);
- memset(output, '\0', sizeof(output));
- memset(map_name, '\0', sizeof(map_name));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
memset(direction, '\0', sizeof(direction));
- sscanf(message, "%d %99[^\n]", &list, map_name);
+ sscanf(message, "%d %99[^\n]", &list, atcmd_player_name);
if (list < 0 || list > 3) {
clif_displaymessage(fd, "Please, enter at least a valid list number (usage: @mapinfo <0-3> [map]).");
return -1;
}
- if (map_name[0] == '\0')
- strcpy(map_name, sd->mapname);
- if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat)
- strcat(map_name, ".gat");
+ if (atcmd_player_name[0] == '\0')
+ strcpy(atcmd_player_name, sd->mapname);
+ if (strstr(atcmd_player_name, ".gat") == NULL && strstr(atcmd_player_name, ".afm") == NULL && strlen(atcmd_player_name) < 13) // 16 - 4 (.gat)
+ strcat(atcmd_player_name, ".gat");
- if ((m_id = map_mapname2mapid(map_name)) < 0) {
+ if ((m_id = map_mapname2mapid(atcmd_player_name)) < 0) {
clif_displaymessage(fd, msg_table[1]); // Map not found.
return -1;
}
clif_displaymessage(fd, "------ Map Info ------");
- sprintf(output, "Map Name: %s", map_name);
- clif_displaymessage(fd, output);
- sprintf(output, "Players In Map: %d", map[m_id].users);
- clif_displaymessage(fd, output);
- sprintf(output, "NPCs In Map: %d", map[m_id].npc_num);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Map Name: %s", atcmd_player_name);
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, "Players In Map: %d", map[m_id].users);
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, "NPCs In Map: %d", map[m_id].npc_num);
+ clif_displaymessage(fd, atcmd_output);
chat_num = 0;
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth &&
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth &&
(cd = (struct chat_data*)map_id2bl(pl_sd->chatID))) {
chat_num++;
}
}
- sprintf(output, "Chats In Map: %d", chat_num);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "Chats In Map: %d", chat_num);
+ clif_displaymessage(fd, atcmd_output);
clif_displaymessage(fd, "------ Map Flags ------");
- sprintf(output, "Player vs Player: %s | No Guild: %s | No Party: %s",
+ sprintf(atcmd_output, "Player vs Player: %s | No Guild: %s | No Party: %s",
(map[m_id].flag.pvp) ? "True" : "False",
(map[m_id].flag.pvp_noguild) ? "True" : "False",
(map[m_id].flag.pvp_noparty) ? "True" : "False");
- clif_displaymessage(fd, output);
- sprintf(output, "Guild vs Guild: %s | No Party: %s", (map[m_id].flag.gvg) ? "True" : "False", (map[m_id].flag.gvg_noparty) ? "True" : "False");
- clif_displaymessage(fd, output);
- sprintf(output, "No Dead Branch: %s", (map[m_id].flag.nobranch) ? "True" : "False");
- clif_displaymessage(fd, output);
- sprintf(output, "No Memo: %s", (map[m_id].flag.nomemo) ? "True" : "False");
- clif_displaymessage(fd, output);
- sprintf(output, "No Penalty: %s", (map[m_id].flag.nopenalty) ? "True" : "False");
- clif_displaymessage(fd, output);
- sprintf(output, "No Return: %s", (map[m_id].flag.noreturn) ? "True" : "False");
- clif_displaymessage(fd, output);
- sprintf(output, "No Save: %s", (map[m_id].flag.nosave) ? "True" : "False");
- clif_displaymessage(fd, output);
- sprintf(output, "No Teleport: %s", (map[m_id].flag.noteleport) ? "True" : "False");
- clif_displaymessage(fd, output);
- sprintf(output, "No Monster Teleport: %s", (map[m_id].flag.monster_noteleport) ? "True" : "False");
- clif_displaymessage(fd, output);
- sprintf(output, "No Zeny Penalty: %s", (map[m_id].flag.nozenypenalty) ? "True" : "False");
- clif_displaymessage(fd, output);
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, "Guild vs Guild: %s | No Party: %s", (map[m_id].flag.gvg) ? "True" : "False", (map[m_id].flag.gvg_noparty) ? "True" : "False");
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, "No Dead Branch: %s", (map[m_id].flag.nobranch) ? "True" : "False");
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, "No Memo: %s", (map[m_id].flag.nomemo) ? "True" : "False");
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, "No Penalty: %s", (map[m_id].flag.nopenalty) ? "True" : "False");
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, "No Return: %s", (map[m_id].flag.noreturn) ? "True" : "False");
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, "No Save: %s", (map[m_id].flag.nosave) ? "True" : "False");
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, "No Teleport: %s", (map[m_id].flag.noteleport) ? "True" : "False");
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, "No Monster Teleport: %s", (map[m_id].flag.monster_noteleport) ? "True" : "False");
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, "No Zeny Penalty: %s", (map[m_id].flag.nozenypenalty) ? "True" : "False");
+ clif_displaymessage(fd, atcmd_output);
switch (list) {
case 0:
@@ -5602,10 +5852,10 @@ int atcommand_mapinfo(
case 1:
clif_displaymessage(fd, "----- Players in Map -----");
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth && strcmp(pl_sd->mapname, map_name) == 0) {
- sprintf(output, "Player '%s' (session #%d) | Location: %d,%d",
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && strcmp(pl_sd->mapname, atcmd_player_name) == 0) {
+ sprintf(atcmd_output, "Player '%s' (session #%d) | Location: %d,%d",
pl_sd->status.name, i, pl_sd->bl.x, pl_sd->bl.y);
- clif_displaymessage(fd, output);
+ clif_displaymessage(fd, atcmd_output);
}
}
break;
@@ -5625,24 +5875,24 @@ int atcommand_mapinfo(
case 9: strcpy(direction, "North"); break;
default: strcpy(direction, "Unknown"); break;
}
- sprintf(output, "NPC %d: %s | Direction: %s | Sprite: %d | Location: %d %d",
- ++i, nd->name, direction, nd->class, nd->bl.x, nd->bl.y);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "NPC %d: %s | Direction: %s | Sprite: %d | Location: %d %d",
+ ++i, nd->name, direction, nd->class_, nd->bl.x, nd->bl.y);
+ clif_displaymessage(fd, atcmd_output);
}
break;
case 3:
clif_displaymessage(fd, "----- Chats in Map -----");
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth &&
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth &&
(cd = (struct chat_data*)map_id2bl(pl_sd->chatID)) &&
- strcmp(pl_sd->mapname, map_name) == 0 &&
+ strcmp(pl_sd->mapname, atcmd_player_name) == 0 &&
cd->usersd[0] == pl_sd) {
- sprintf(output, "Chat %d: %s | Player: %s | Location: %d %d",
+ sprintf(atcmd_output, "Chat %d: %s | Player: %s | Location: %d %d",
i, cd->title, pl_sd->status.name, cd->bl.x, cd->bl.y);
- clif_displaymessage(fd, output);
- sprintf(output, " Users: %d/%d | Password: %s | Public: %s",
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, " Users: %d/%d | Password: %s | Public: %s",
cd->users, cd->limit, cd->pass, (cd->pub) ? "Yes" : "No");
- clif_displaymessage(fd, output);
+ clif_displaymessage(fd, atcmd_output);
}
}
break;
@@ -5663,21 +5913,22 @@ int atcommand_mount_peco(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
if (sd->disguise > 0) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris]
clif_displaymessage(fd, msg_table[212]); // Cannot mount a Peco while in disguise.
return -1;
}
if (!pc_isriding(sd)) { // if actually no peco
- if (sd->status.class == 7 || sd->status.class == 14 || sd->status.class == 4008 || sd->status.class == 4015) {
- if (sd->status.class == 7)
- sd->status.class = sd->view_class = 13;
- else if (sd->status.class == 14)
- sd->status.class = sd->view_class = 21;
- else if (sd->status.class == 4008)
- sd->status.class = sd->view_class = 4014;
- else if (sd->status.class == 4015)
- sd->status.class = sd->view_class = 4022;
+ if (sd->status.class_ == 7 || sd->status.class_ == 14 || sd->status.class_ == 4008 || sd->status.class_ == 4015) {
+ if (sd->status.class_ == 7)
+ sd->status.class_ = sd->view_class = 13;
+ else if (sd->status.class_ == 14)
+ sd->status.class_ = sd->view_class = 21;
+ else if (sd->status.class_ == 4008)
+ sd->status.class_ = sd->view_class = 4014;
+ else if (sd->status.class_ == 4015)
+ sd->status.class_ = sd->view_class = 4022;
pc_setoption(sd, sd->status.option | 0x0020);
clif_displaymessage(fd, msg_table[102]); // Mounted Peco.
} else {
@@ -5685,14 +5936,14 @@ int atcommand_mount_peco(
return -1;
}
} else {
- if (sd->status.class == 13)
- sd->status.class = sd->view_class = 7;
- else if (sd->status.class == 21)
- sd->status.class = sd->view_class = 14;
- else if (sd->status.class == 4014)
- sd->status.class = sd->view_class = 4008;
- else if (sd->status.class == 4022)
- sd->status.class = sd->view_class = 4015;
+ if (sd->status.class_ == 13)
+ sd->status.class_ = sd->view_class = 7;
+ else if (sd->status.class_ == 21)
+ sd->status.class_ = sd->view_class = 14;
+ else if (sd->status.class_ == 4014)
+ sd->status.class_ = sd->view_class = 4008;
+ else if (sd->status.class_ == 4022)
+ sd->status.class_ = sd->view_class = 4015;
pc_setoption(sd, sd->status.option & ~0x0020);
clif_displaymessage(fd, msg_table[214]); // Unmounted Peco.
}
@@ -5708,32 +5959,32 @@ int atcommand_char_mount_peco(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
struct map_session_data *pl_sd;
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
clif_displaymessage(fd, "Please, enter a player name (usage: @charmountpeco <char_name>).");
return -1;
}
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
if (pl_sd->disguise > 0) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris]
clif_displaymessage(fd, msg_table[215]); // This player cannot mount a Peco while in disguise.
return -1;
}
if (!pc_isriding(pl_sd)) { // if actually no peco
- if (pl_sd->status.class == 7 || pl_sd->status.class == 14 || pl_sd->status.class == 4008 || pl_sd->status.class == 4015) {
- if (pl_sd->status.class == 7)
- pl_sd->status.class = pl_sd->view_class = 13;
- else if (pl_sd->status.class == 14)
- pl_sd->status.class = pl_sd->view_class = 21;
- else if (pl_sd->status.class == 4008)
- pl_sd->status.class = pl_sd->view_class = 4014;
- else if (pl_sd->status.class == 4015)
- pl_sd->status.class = pl_sd->view_class = 4022;
+ if (pl_sd->status.class_ == 7 || pl_sd->status.class_ == 14 || pl_sd->status.class_ == 4008 || pl_sd->status.class_ == 4015) {
+ if (pl_sd->status.class_ == 7)
+ pl_sd->status.class_ = pl_sd->view_class = 13;
+ else if (pl_sd->status.class_ == 14)
+ pl_sd->status.class_ = pl_sd->view_class = 21;
+ else if (pl_sd->status.class_ == 4008)
+ pl_sd->status.class_ = pl_sd->view_class = 4014;
+ else if (pl_sd->status.class_ == 4015)
+ pl_sd->status.class_ = pl_sd->view_class = 4022;
pc_setoption(pl_sd, pl_sd->status.option | 0x0020);
clif_displaymessage(fd, msg_table[216]); // Now, this player mounts a peco.
} else {
@@ -5741,14 +5992,14 @@ int atcommand_char_mount_peco(
return -1;
}
} else {
- if (pl_sd->status.class == 13)
- pl_sd->status.class = pl_sd->view_class = 7;
- else if (pl_sd->status.class == 21)
- pl_sd->status.class = pl_sd->view_class = 14;
- else if (pl_sd->status.class == 4014)
- pl_sd->status.class = pl_sd->view_class = 4008;
- else if (pl_sd->status.class == 4022)
- pl_sd->status.class = pl_sd->view_class = 4015;
+ if (pl_sd->status.class_ == 13)
+ pl_sd->status.class_ = pl_sd->view_class = 7;
+ else if (pl_sd->status.class_ == 21)
+ pl_sd->status.class_ = pl_sd->view_class = 14;
+ else if (pl_sd->status.class_ == 4014)
+ pl_sd->status.class_ = pl_sd->view_class = 4008;
+ else if (pl_sd->status.class_ == 4022)
+ pl_sd->status.class_ = pl_sd->view_class = 4015;
pc_setoption(pl_sd, pl_sd->status.option & ~0x0020);
clif_displaymessage(fd, msg_table[218]); // Now, this player has not more peco.
}
@@ -5769,11 +6020,11 @@ int atcommand_guildspy(
const char* command, const char* message)
{
char guild_name[100];
- char output[200];
struct guild *g;
+ nullpo_retr(-1, sd);
memset(guild_name, '\0', sizeof(guild_name));
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message || sscanf(message, "%99[^\n]", guild_name) < 1) {
clif_displaymessage(fd, "Please, enter a guild name/id (usage: @guildspy <guild_name/id>).");
@@ -5784,12 +6035,12 @@ int atcommand_guildspy(
(g = guild_search(atoi(message))) != NULL) {
if (sd->guildspy == g->guild_id) {
sd->guildspy = 0;
- sprintf(output, msg_table[103], g->name); // No longer spying on the %s guild.
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[103], g->name); // No longer spying on the %s guild.
+ clif_displaymessage(fd, atcmd_output);
} else {
sd->guildspy = g->guild_id;
- sprintf(output, msg_table[104], g->name); // Spying on the %s guild.
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[104], g->name); // Spying on the %s guild.
+ clif_displaymessage(fd, atcmd_output);
}
} else {
clif_displaymessage(fd, msg_table[94]); // Incorrect name/ID, or no one from the guild is online.
@@ -5808,11 +6059,11 @@ int atcommand_partyspy(
const char* command, const char* message)
{
char party_name[100];
- char output[200];
struct party *p;
+ nullpo_retr(-1, sd);
memset(party_name, '\0', sizeof(party_name));
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message || sscanf(message, "%99[^\n]", party_name) < 1) {
clif_displaymessage(fd, "Please, enter a party name/id (usage: @partyspy <party_name/id>).");
@@ -5823,12 +6074,12 @@ int atcommand_partyspy(
(p = party_search(atoi(message))) != NULL) {
if (sd->partyspy == p->party_id) {
sd->partyspy = 0;
- sprintf(output, msg_table[105], p->name); // No longer spying on the %s party.
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[105], p->name); // No longer spying on the %s party.
+ clif_displaymessage(fd, atcmd_output);
} else {
sd->partyspy = p->party_id;
- sprintf(output, msg_table[106], p->name); // Spying on the %s party.
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[106], p->name); // Spying on the %s party.
+ clif_displaymessage(fd, atcmd_output);
}
} else {
clif_displaymessage(fd, msg_table[96]); // Incorrect name or ID, or no one from the party is online.
@@ -5847,6 +6098,7 @@ int atcommand_repairall(
const char* command, const char* message)
{
int count, i;
+ nullpo_retr(-1, sd);
count = 0;
for (i = 0; i < MAX_INVENTORY; i++) {
@@ -5869,22 +6121,22 @@ int atcommand_repairall(
return 0;
}
-/* Removed @nuke for now in favor of alchemist marine sphere skill [Valaris]
+// Removed @nuke for now in favor of alchemist marine sphere skill [Valaris]
int atcommand_nuke(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
struct map_session_data *pl_sd;
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
clif_displaymessage(fd, "Please, enter a player name (usage: @nuke <char name>).");
return -1;
}
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can kill only lower or same GM level
skill_castend_damage_id(&pl_sd->bl, &pl_sd->bl, NPC_SELFDESTRUCTION, 99, gettick(), 0);
clif_displaymessage(fd, msg_table[109]); // Player has been nuked!
@@ -5899,7 +6151,7 @@ int atcommand_nuke(
return 0;
}
-*/
+
/*==========================================
*
@@ -5909,11 +6161,12 @@ int atcommand_enablenpc(const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
char NPCname[100];
+ nullpo_retr(-1, sd);
memset(NPCname, '\0', sizeof(NPCname));
if (!message || !*message || sscanf(message, "%99[^\n]", NPCname) < 1) {
- clif_displaymessage(fd, "Please, enter a NPC name (usage: @npcon <NPC_name>).");
+ clif_displaymessage(fd, "Please, enter a NPC name (usage: @enablenpc <NPC_name>).");
return -1;
}
@@ -5932,10 +6185,11 @@ int atcommand_enablenpc(const int fd, struct map_session_data* sd,
*
*------------------------------------------
*/
-int atcommand_disablenpc(const int fd, struct map_session_data* sd,
+int atcommand_hidenpc(const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
char NPCname[100];
+ nullpo_retr(-1, sd);
memset(NPCname, '\0', sizeof(NPCname));
@@ -5955,6 +6209,31 @@ int atcommand_disablenpc(const int fd, struct map_session_data* sd,
return 0;
}
+int atcommand_disablenpc(const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ struct npc_data *nd;
+ char NPCname[100];
+ nullpo_retr(-1, sd);
+
+ memset(NPCname, '\0', sizeof(NPCname));
+
+ if (!message || !*message || sscanf(message, "%99[^\n]", NPCname) < 1) {
+ clif_displaymessage(fd, "Please, enter a NPC name (usage: @npcoff <NPC_name>).");
+ return -1;
+ }
+
+ if ((nd = npc_name2id(NPCname)) != NULL) {
+ npc_unload(nd);
+ clif_displaymessage(fd, msg_table[112]); // Npc Disabled.
+ } else {
+ clif_displaymessage(fd, msg_table[111]); // This NPC doesn't exist.
+ return -1;
+ }
+
+ return 0;
+}
+
/*==========================================
* time in txt for time command (by [Yor])
*------------------------------------------
@@ -6010,6 +6289,7 @@ int atcommand_servertime(const int fd, struct map_session_data* sd,
time_t time_server; // variable for number of seconds (used with time() function)
struct tm *datetime; // variable for time in structure ->tm_mday, ->tm_sec, ...
char temp[256];
+ nullpo_retr(-1, sd);
memset(temp, '\0', sizeof(temp));
@@ -6082,17 +6362,16 @@ int atcommand_chardelitem(const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
struct map_session_data *pl_sd;
- char character[100];
char item_name[100];
int i, number = 0, item_id, item_position, count;
- char output[200];
struct item_data *item_data;
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
memset(item_name, '\0', sizeof(item_name));
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
- if (!message || !*message || sscanf(message, "%s %d %99[^\n]", item_name, &number, character) < 3 || number < 1) {
+ if (!message || !*message || sscanf(message, "%s %d %99[^\n]", item_name, &number, atcmd_player_name) < 3 || number < 1) {
clif_displaymessage(fd, "Please, enter an item name/id, a quantity and a player name (usage: @chardelitem <item_name_or_ID> <quantity> <player>).");
return -1;
}
@@ -6103,7 +6382,7 @@ int atcommand_chardelitem(const int fd, struct map_session_data* sd,
item_id = item_data->nameid;
if (item_id > 500) {
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can kill only lower or same level
item_position = pc_search_inventory(pl_sd, item_id);
if (item_position >= 0) {
@@ -6113,13 +6392,13 @@ int atcommand_chardelitem(const int fd, struct map_session_data* sd,
count++;
item_position = pc_search_inventory(pl_sd, item_id); // for next loop
}
- sprintf(output, msg_table[113], count); // %d item(s) removed by a GM.
- clif_displaymessage(pl_sd->fd, output);
+ sprintf(atcmd_output, msg_table[113], count); // %d item(s) removed by a GM.
+ clif_displaymessage(pl_sd->fd, atcmd_output);
if (number == count)
- sprintf(output, msg_table[114], count); // %d item(s) removed from the player.
+ sprintf(atcmd_output, msg_table[114], count); // %d item(s) removed from the player.
else
- sprintf(output, msg_table[115], count, count, number); // %d item(s) removed. Player had only %d on %d items.
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, msg_table[115], count, count, number); // %d item(s) removed. Player had only %d on %d items.
+ clif_displaymessage(fd, atcmd_output);
} else {
clif_displaymessage(fd, msg_table[116]); // Character does not have the item.
return -1;
@@ -6149,18 +6428,18 @@ int atcommand_jail(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
struct map_session_data *pl_sd;
int x, y;
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
clif_displaymessage(fd, "Please, enter a player name (usage: @jail <char_name>).");
return -1;
}
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can jail only lower or same GM
switch(rand() % 2) {
case 0:
@@ -6201,23 +6480,22 @@ int atcommand_unjail(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
struct map_session_data *pl_sd;
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
clif_displaymessage(fd, "Please, enter a player name (usage: @unjail/@discharge <char_name>).");
return -1;
}
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can jail only lower or same GM
if (pl_sd->bl.m != map_mapname2mapid("sec_pri.gat")) {
clif_displaymessage(fd, msg_table[119]); // This player is not in jails.
return -1;
- } else if (pc_setpos(pl_sd, "prontera.gat", 156, 191, 3) == 0) {
- pc_setsavepoint(pl_sd, "prontera.gat", 156, 191); // Save char respawn point in Prontera
+ } else if (pc_setpos(pl_sd, "prontera.gat", 0, 0, 3) == 0) { //old coords: 156,191
+ pc_setsavepoint(pl_sd, "prontera.gat", 0, 0); // Save char respawn point in Prontera
clif_displaymessage(pl_sd->fd, msg_table[120]); // GM has discharge you.
clif_displaymessage(fd, msg_table[121]); // Player warped to Prontera.
} else {
@@ -6245,6 +6523,7 @@ int atcommand_disguise(
const char* command, const char* message)
{
int mob_id = 0;
+ nullpo_retr(-1, sd);
if (!message || !*message) {
clif_displaymessage(fd, "Please, enter a Monster/NPC name/id (usage: @disguise <monster_name_or_monster_ID>).");
@@ -6257,7 +6536,7 @@ int atcommand_disguise(
if ((mob_id >= 46 && mob_id <= 125) || (mob_id >= 700 && mob_id <= 718) || // NPC
(mob_id >= 721 && mob_id <= 755) || (mob_id >= 757 && mob_id <= 811) || // NPC
(mob_id >= 813 && mob_id <= 834) || // NPC
- (mob_id > 1000 && mob_id < 1521)) { // monsters
+ (mob_id > 1000 && mob_id < 1582)) { // monsters
if (pc_isriding(sd)) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris]
clif_displaymessage(fd, msg_table[227]); // Cannot wear disguise while riding a Peco.
return -1;
@@ -6275,6 +6554,50 @@ int atcommand_disguise(
}
/*==========================================
+ * DisguiseAll
+ *------------------------------------------
+ */
+
+int atcommand_disguiseall(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ int mob_id=0, i=0;
+ struct map_session_data *pl_sd;
+ nullpo_retr(-1, sd);
+
+ if (!message || !*message) {
+ clif_displaymessage(fd, "Please, enter a Monster/NPC name/id (usage: @disguiseall <monster_name_or_monster_ID>).");
+ return -1;
+ }
+
+ if ((mob_id = mobdb_searchname(message)) == 0) // check name first (to avoid possible name begining by a number)
+ mob_id = atoi(message);
+
+ if ((mob_id >= 46 && mob_id <= 125) || (mob_id >= 700 && mob_id <= 718) || // NPC
+ (mob_id >= 721 && mob_id <= 755) || (mob_id >= 757 && mob_id <= 811) || // NPC
+ (mob_id >= 813 && mob_id <= 834) || // NPC
+ (mob_id > 1000 && mob_id < 1582)) { // monsters
+ for(i=0; i < fd_max; i++) {
+ if(session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) {
+ if(pc_isriding(pl_sd)) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris]
+ clif_displaymessage(fd, msg_table[227]); // Cannot wear disguise while riding a Peco.
+ } else {
+ pl_sd->disguiseflag = 1; // set to override items with disguise script [Valaris]
+ pl_sd->disguise = mob_id;
+ pc_setpos(pl_sd, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y, 3);
+ }
+ }
+ }
+ clif_displaymessage(fd, msg_table[122]); // Disguise applied.
+ } else {
+ return -1;
+ }
+
+ return 0;
+}
+
+/*==========================================
* @undisguise by [Yor]
*------------------------------------------
*/
@@ -6282,6 +6605,7 @@ int atcommand_undisguise(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
if (sd->disguise) {
clif_clearchar(&sd->bl, 9);
sd->disguise = 0;
@@ -6296,6 +6620,30 @@ int atcommand_undisguise(
}
/*==========================================
+ * UndisguiseAll
+ *------------------------------------------
+ */
+int atcommand_undisguiseall(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ struct map_session_data *pl_sd;
+ int i;
+ nullpo_retr(-1, sd);
+
+ for(i=0; i < fd_max; i++) {
+ if(session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && pl_sd->disguise) {
+ clif_clearchar(&pl_sd->bl, 9);
+ pl_sd->disguise = 0;
+ pc_setpos(pl_sd, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y, 3);
+ }
+ }
+ clif_displaymessage(fd, msg_table[124]); // Undisguise applied.
+
+ return 0;
+}
+
+/*==========================================
* @broadcast by [Valaris]
*------------------------------------------
*/
@@ -6303,17 +6651,17 @@ int atcommand_broadcast(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char output[200];
+ nullpo_retr(-1, sd);
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message) {
clif_displaymessage(fd, "Please, enter a message (usage: @broadcast <message>).");
return -1;
}
- sprintf(output, "%s : %s", sd->status.name, message);
- intif_GMmessage(output, strlen(output) + 1, 0);
+ sprintf(atcmd_output, "%s : %s", sd->status.name, message);
+ intif_GMmessage(atcmd_output, strlen(atcmd_output) + 1, 0);
return 0;
}
@@ -6326,18 +6674,18 @@ int atcommand_localbroadcast(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char output[200];
+ nullpo_retr(-1, sd);
- memset(output, '\0', sizeof(output));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message) {
clif_displaymessage(fd, "Please, enter a message (usage: @localbroadcast <message>).");
return -1;
}
- sprintf(output, "%s : %s", sd->status.name, message);
+ sprintf(atcmd_output, "%s : %s", sd->status.name, message);
- clif_GMmessage(&sd->bl, output, strlen(output) + 1, 1); // 1: ALL_SAMEMAP
+ clif_GMmessage(&sd->bl, atcmd_output, strlen(atcmd_output) + 1, 1); // 1: ALL_SAMEMAP
return 0;
}
@@ -6351,14 +6699,14 @@ int atcommand_chardisguise(
const char* command, const char* message)
{
int mob_id;
- char character[100];
char mob_name[100];
struct map_session_data* pl_sd;
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
memset(mob_name, '\0', sizeof(mob_name));
- if (!message || !*message || sscanf(message, "%s %99[^\n]", mob_name, character) < 2) {
+ if (!message || !*message || sscanf(message, "%s %99[^\n]", mob_name, atcmd_player_name) < 2) {
clif_displaymessage(fd, "Please, enter a Monster/NPC name/id and a player name (usage: @chardisguise <monster_name_or_monster_ID> <char name>).");
return -1;
}
@@ -6366,7 +6714,7 @@ int atcommand_chardisguise(
if ((mob_id = mobdb_searchname(mob_name)) == 0) // check name first (to avoid possible name begining by a number)
mob_id = atoi(mob_name);
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can disguise only lower or same level
if ((mob_id >= 46 && mob_id <= 125) || (mob_id >= 700 && mob_id <= 718) || // NPC
(mob_id >= 721 && mob_id <= 755) || (mob_id >= 757 && mob_id <= 811) || // NPC
@@ -6404,17 +6752,17 @@ int atcommand_charundisguise(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
struct map_session_data* pl_sd;
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
clif_displaymessage(fd, "Please, enter a player name (usage: @charundisguise <char name>).");
return -1;
}
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can undisguise only lower or same level
if (pl_sd->disguise) {
clif_clearchar(&pl_sd->bl, 9);
@@ -6447,6 +6795,7 @@ int atcommand_email(
{
char actual_email[100];
char new_email[100];
+ nullpo_retr(-1, sd);
memset(actual_email, '\0', sizeof(actual_email));
memset(new_email, '\0', sizeof(new_email));
@@ -6486,6 +6835,7 @@ int atcommand_effect(
{
struct map_session_data *pl_sd;
int type = 0, flag = 0, i;
+ nullpo_retr(-1, sd);
if (!message || !*message || sscanf(message, "%d %d", &type,&flag) < 2) {
clif_displaymessage(fd, "Please, enter at least a option (usage: @effect <type+>).");
@@ -6497,7 +6847,7 @@ int atcommand_effect(
}
else{
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) {
clif_specialeffect(&pl_sd->bl, type, flag);
clif_displaymessage(pl_sd->fd, msg_table[229]); // Your effect has changed.
}
@@ -6508,203 +6858,6 @@ int atcommand_effect(
}
/*==========================================
- * @charitemlist <character>: Displays the list of a player's items.
- *------------------------------------------
- */
-int
-atcommand_character_item_list(
- const int fd, struct map_session_data* sd,
- const char* command, const char* message)
-{
- struct map_session_data *pl_sd;
- struct item_data *item_data, *item_temp;
- int i, j, equip, count, counter, counter2;
- char character[100], output[200], equipstr[100], outputtmp[200];
-
- memset(character, '\0', sizeof(character));
- memset(output, '\0', sizeof(output));
- memset(equipstr, '\0', sizeof(equipstr));
- memset(outputtmp, '\0', sizeof(outputtmp));
-
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
- clif_displaymessage(fd, "Please, enter a player name (usage: @charitemlist <char name>).");
- return -1;
- }
-
- if ((pl_sd = map_nick2sd(character)) != NULL) {
- if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can look items only lower or same level
- counter = 0;
- count = 0;
- for (i = 0; i < MAX_INVENTORY; i++) {
- if (pl_sd->status.inventory[i].nameid > 0 && (item_data = itemdb_search(pl_sd->status.inventory[i].nameid)) != NULL) {
- counter = counter + pl_sd->status.inventory[i].amount;
- count++;
- if (count == 1) {
- sprintf(output, "------ Items list of '%s' ------", pl_sd->status.name);
- clif_displaymessage(fd, output);
- }
- if ((equip = pl_sd->status.inventory[i].equip)) {
- strcpy(equipstr, "| equiped: ");
- if (equip & 4)
- strcat(equipstr, "robe/gargment, ");
- if (equip & 8)
- strcat(equipstr, "left accessory, ");
- if (equip & 16)
- strcat(equipstr, "body/armor, ");
- if ((equip & 34) == 2)
- strcat(equipstr, "right hand, ");
- if ((equip & 34) == 32)
- strcat(equipstr, "left hand, ");
- if ((equip & 34) == 34)
- strcat(equipstr, "both hands, ");
- if (equip & 64)
- strcat(equipstr, "feet, ");
- if (equip & 128)
- strcat(equipstr, "right accessory, ");
- if ((equip & 769) == 1)
- strcat(equipstr, "lower head, ");
- if ((equip & 769) == 256)
- strcat(equipstr, "top head, ");
- if ((equip & 769) == 257)
- strcat(equipstr, "lower/top head, ");
- if ((equip & 769) == 512)
- strcat(equipstr, "mid head, ");
- if ((equip & 769) == 512)
- strcat(equipstr, "lower/mid head, ");
- if ((equip & 769) == 769)
- strcat(equipstr, "lower/mid/top head, ");
- // remove final ', '
- equipstr[strlen(equipstr) - 2] = '\0';
- } else
- memset(equipstr, '\0', sizeof(equipstr));
- if (sd->status.inventory[i].refine)
- sprintf(output, "%d %s %+d (%s %+d, id: %d) %s", pl_sd->status.inventory[i].amount, item_data->name, pl_sd->status.inventory[i].refine, item_data->jname, pl_sd->status.inventory[i].refine, pl_sd->status.inventory[i].nameid, equipstr);
- else
- sprintf(output, "%d %s (%s, id: %d) %s", pl_sd->status.inventory[i].amount, item_data->name, item_data->jname, pl_sd->status.inventory[i].nameid, equipstr);
- clif_displaymessage(fd, output);
- memset(output, '\0', sizeof(output));
- counter2 = 0;
- for (j = 0; j < item_data->slot; j++) {
- if (pl_sd->status.inventory[i].card[j]) {
- if ((item_temp = itemdb_search(pl_sd->status.inventory[i].card[j])) != NULL) {
- if (output[0] == '\0')
- sprintf(outputtmp, " -> (card(s): #%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname);
- else
- sprintf(outputtmp, "#%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname);
- strcat(output, outputtmp);
- }
- }
- }
- if (output[0] != '\0') {
- output[strlen(output) - 2] = ')';
- output[strlen(output) - 1] = '\0';
- clif_displaymessage(fd, output);
- }
- }
- }
- if (count == 0)
- clif_displaymessage(fd, "No item found on this player.");
- else {
- sprintf(output, "%d item(s) found in %d kind(s) of items.", counter, count);
- clif_displaymessage(fd, output);
- }
- } else {
- clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
- return -1;
- }
- } else {
- clif_displaymessage(fd, msg_table[3]); // Character not found.
- return -1;
- }
-
- return 0;
-}
-
-/*==========================================
- * @charstoragelist <character>: Displays the items list of a player's storage.
- *------------------------------------------
- */
-int
-atcommand_character_storage_list(
- const int fd, struct map_session_data* sd,
- const char* command, const char* message)
-{
- struct storage *stor;
- struct map_session_data *pl_sd;
- struct item_data *item_data, *item_temp;
- int i, j, count, counter, counter2;
- char character[100], output[200], outputtmp[200];
-
- memset(character, '\0', sizeof(character));
- memset(output, '\0', sizeof(output));
- memset(outputtmp, '\0', sizeof(outputtmp));
-
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
- clif_displaymessage(fd, "Please, enter a player name (usage: @charitemlist <char name>).");
- return -1;
- }
-
- if ((pl_sd = map_nick2sd(character)) != NULL) {
- if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can look items only lower or same level
- if((stor = account2storage2(pl_sd->status.account_id)) != NULL) {
- counter = 0;
- count = 0;
- for (i = 0; i < MAX_STORAGE; i++) {
- if (stor->storage[i].nameid > 0 && (item_data = itemdb_search(stor->storage[i].nameid)) != NULL) {
- counter = counter + stor->storage[i].amount;
- count++;
- if (count == 1) {
- sprintf(output, "------ Storage items list of '%s' ------", pl_sd->status.name);
- clif_displaymessage(fd, output);
- }
- if (stor->storage[i].refine)
- sprintf(output, "%d %s %+d (%s %+d, id: %d)", stor->storage[i].amount, item_data->name, stor->storage[i].refine, item_data->jname, stor->storage[i].refine, stor->storage[i].nameid);
- else
- sprintf(output, "%d %s (%s, id: %d)", stor->storage[i].amount, item_data->name, item_data->jname, stor->storage[i].nameid);
- clif_displaymessage(fd, output);
- memset(output, '\0', sizeof(output));
- counter2 = 0;
- for (j = 0; j < item_data->slot; j++) {
- if (stor->storage[i].card[j]) {
- if ((item_temp = itemdb_search(stor->storage[i].card[j])) != NULL) {
- if (output[0] == '\0')
- sprintf(outputtmp, " -> (card(s): #%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname);
- else
- sprintf(outputtmp, "#%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname);
- strcat(output, outputtmp);
- }
- }
- }
- if (output[0] != '\0') {
- output[strlen(output) - 2] = ')';
- output[strlen(output) - 1] = '\0';
- clif_displaymessage(fd, output);
- }
- }
- }
- if (count == 0)
- clif_displaymessage(fd, "No item found in the storage of this player.");
- else {
- sprintf(output, "%d item(s) found in %d kind(s) of items.", counter, count);
- clif_displaymessage(fd, output);
- }
- } else {
- clif_displaymessage(fd, "This player has no storage.");
- return 0;
- }
- } else {
- clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
- return -1;
- }
- } else {
- clif_displaymessage(fd, msg_table[3]); // Character not found.
- return -1;
- }
-
- return 0;
-}
-
-/*==========================================
* @charcartlist <character>: Displays the items list of a player's cart.
*------------------------------------------
*/
@@ -6713,21 +6866,22 @@ atcommand_character_cart_list(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ char outputtmp[200];
struct map_session_data *pl_sd;
struct item_data *item_data, *item_temp;
int i, j, count, counter, counter2;
- char character[100], output[200], outputtmp[200];
+ nullpo_retr(-1, sd);
- memset(character, '\0', sizeof(character));
- memset(output, '\0', sizeof(output));
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
memset(outputtmp, '\0', sizeof(outputtmp));
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ if (!message || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
clif_displaymessage(fd, "Please, enter a player name (usage: @charitemlist <char name>).");
return -1;
}
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can look items only lower or same level
counter = 0;
count = 0;
@@ -6736,39 +6890,39 @@ atcommand_character_cart_list(
counter = counter + pl_sd->status.cart[i].amount;
count++;
if (count == 1) {
- sprintf(output, "------ Cart items list of '%s' ------", pl_sd->status.name);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "------ Cart items list of '%s' ------", pl_sd->status.name);
+ clif_displaymessage(fd, atcmd_output);
}
if (pl_sd->status.cart[i].refine)
- sprintf(output, "%d %s %+d (%s %+d, id: %d)", pl_sd->status.cart[i].amount, item_data->name, pl_sd->status.cart[i].refine, item_data->jname, pl_sd->status.cart[i].refine, pl_sd->status.cart[i].nameid);
+ sprintf(atcmd_output, "%d %s %+d (%s %+d, id: %d)", pl_sd->status.cart[i].amount, item_data->name, pl_sd->status.cart[i].refine, item_data->jname, pl_sd->status.cart[i].refine, pl_sd->status.cart[i].nameid);
else
- sprintf(output, "%d %s (%s, id: %d)", pl_sd->status.cart[i].amount, item_data->name, item_data->jname, pl_sd->status.cart[i].nameid);
- clif_displaymessage(fd, output);
- memset(output, '\0', sizeof(output));
+ sprintf(atcmd_output, "%d %s (%s, id: %d)", pl_sd->status.cart[i].amount, item_data->name, item_data->jname, pl_sd->status.cart[i].nameid);
+ clif_displaymessage(fd, atcmd_output);
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
counter2 = 0;
for (j = 0; j < item_data->slot; j++) {
if (pl_sd->status.cart[i].card[j]) {
- if ((item_temp = itemdb_search(pl_sd->status.cart[i].card[j])) != NULL) {
- if (output[0] == '\0')
+ if ( (item_temp = itemdb_search(pl_sd->status.cart[i].card[j])) != NULL) {
+ if (atcmd_output[0] == '\0')
sprintf(outputtmp, " -> (card(s): #%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname);
else
sprintf(outputtmp, "#%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname);
- strcat(output, outputtmp);
+ strcat(atcmd_output, outputtmp);
}
}
}
- if (output[0] != '\0') {
- output[strlen(output) - 2] = ')';
- output[strlen(output) - 1] = '\0';
- clif_displaymessage(fd, output);
+ if (atcmd_output[0] != '\0') {
+ atcmd_output[strlen(atcmd_output) - 2] = ')';
+ atcmd_output[strlen(atcmd_output) - 1] = '\0';
+ clif_displaymessage(fd, atcmd_output);
}
}
}
if (count == 0)
clif_displaymessage(fd, "No item found in the cart of this player.");
else {
- sprintf(output, "%d item(s) found in %d kind(s) of items.", counter, count);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "%d item(s) found in %d kind(s) of items.", counter, count);
+ clif_displaymessage(fd, atcmd_output);
}
} else {
clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
@@ -6792,6 +6946,7 @@ atcommand_killer(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
sd->special_state.killer = !sd->special_state.killer;
if(sd->special_state.killer)
@@ -6812,6 +6967,7 @@ atcommand_killable(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
sd->special_state.killable = !sd->special_state.killable;
if(sd->special_state.killable)
@@ -6833,6 +6989,7 @@ atcommand_charkillable(
const char* command, const char* message)
{
struct map_session_data *pl_sd = NULL;
+ nullpo_retr(-1, sd);
if (!message || !*message)
return -1;
@@ -6861,6 +7018,7 @@ atcommand_skillon(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
map[sd->bl.m].flag.noskill = 0;
clif_displaymessage(fd, msg_table[244]);
return 0;
@@ -6876,6 +7034,7 @@ atcommand_skilloff(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
+ nullpo_retr(-1, sd);
map[sd->bl.m].flag.noskill = 1;
clif_displaymessage(fd, msg_table[243]);
return 0;
@@ -6891,31 +7050,29 @@ int
atcommand_npcmove(const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char character[100];
int x = 0, y = 0;
struct npc_data *nd = 0;
-
- if( sd == NULL )
- return -1;
+ nullpo_retr(-1, sd);
+
if (!message || !*message)
return -1;
- memset(character, '\0', sizeof character);
+ memset(atcmd_player_name, '\0', sizeof atcmd_player_name);
- if (sscanf(message, "%d %d %99[^\n]", &x, &y, character) < 4)
+ if (sscanf(message, "%d %d %99[^\n]", &x, &y, atcmd_player_name) < 3) {
+ clif_displaymessage(fd, "Usage: @npcmove <X> <Y> <npc_name>");
return -1;
+ }
- nd=npc_name2id(character);
- if (nd==NULL)
- return -1;
+ nullpo_retr(-1, (nd = npc_name2id(atcmd_player_name)));
- npc_enable(character, 0);
- nd->bl.x = x;
- nd->bl.y = y;
- npc_enable(character, 1);
+ npc_enable(atcmd_player_name, 0);
+ nd->bl.x = x;
+ nd->bl.y = y;
+ npc_enable(atcmd_player_name, 1);
- return 0;
+ return 0;
}
/*==========================================
@@ -6929,24 +7086,24 @@ atcommand_addwarp(const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
char w1[64], w3[64], w4[64];
- char map[30], output[200];
int x,y,ret;
+ nullpo_retr(-1, sd);
if (!message || !*message)
return -1;
- if (sscanf(message, "%99s %d %d[^\n]", map, &x, &y ) < 3)
+ if (sscanf(message, "%99s %d %d[^\n]", atcmd_player_name, &x, &y ) < 3)
return -1;
sprintf(w1,"%s,%d,%d", sd->mapname, sd->bl.x, sd->bl.y);
- sprintf(w3,"%s%d%d%d%d", map,sd->bl.x, sd->bl.y, x, y);
- sprintf(w4,"1,1,%s.gat,%d,%d", map, x, y);
+ sprintf(w3,"%s%d%d%d%d", atcmd_player_name,sd->bl.x, sd->bl.y, x, y);
+ sprintf(w4,"1,1,%s.gat,%d,%d", atcmd_player_name, x, y);
ret = npc_parse_warp(w1, "warp", w3, w4);
- sprintf(output, "New warp NPC => %s",w3);
+ sprintf(atcmd_output, "New warp NPC => %s",w3);
- clif_displaymessage(fd, output);
+ clif_displaymessage(fd, atcmd_output);
return ret;
}
@@ -6962,6 +7119,7 @@ atcommand_follow(const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
struct map_session_data *pl_sd = NULL;
+ nullpo_retr(-1, sd);
if (!message || !*message)
return -1;
@@ -6974,33 +7132,6 @@ atcommand_follow(const int fd, struct map_session_data* sd,
/*==========================================
- * @chareffect by [MouseJstr]
- *
- * Create a effect localized on another character
- *------------------------------------------
- */
-int
-atcommand_chareffect(const int fd, struct map_session_data* sd,
- const char* command, const char* message)
-{
- struct map_session_data *pl_sd = NULL;
- char target[255];
- int type = 0;
-
- if (!message || !*message || sscanf(message, "%d %s", &type, target) != 2) {
- clif_displaymessage(fd, "usage: @chareffect <type+> <target>.");
- return -1;
- }
-
- if((pl_sd=map_nick2sd((char *) target)) == NULL)
- return -1;
-
- clif_specialeffect(&pl_sd->bl, type, 0);
- clif_displaymessage(fd, msg_table[229]); // Your effect has changed.
-
- return 0;
-}
-/*==========================================
* @dropall by [MouseJstr]
*
* Drop all your possession on the ground
@@ -7011,10 +7142,11 @@ atcommand_dropall(const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
int i;
+ nullpo_retr(-1, sd);
for (i = 0; i < MAX_INVENTORY; i++) {
if (sd->status.inventory[i].amount) {
if(sd->status.inventory[i].equip != 0)
- pc_unequipitem(sd, i, 0, BF_NORMAL);
+ pc_unequipitem(sd, i, 3);
pc_dropitem(sd, i, sd->status.inventory[i].amount);
}
}
@@ -7022,7 +7154,7 @@ atcommand_dropall(const int fd, struct map_session_data* sd,
}
/*==========================================
* @chardropall by [MouseJstr]
- *
+ *
* Throw all the characters possessions on the ground. Normally
* done in response to them being disrespectful of a GM
*------------------------------------------
@@ -7033,6 +7165,7 @@ atcommand_chardropall(const int fd, struct map_session_data* sd,
{
int i;
struct map_session_data *pl_sd = NULL;
+ nullpo_retr(-1, sd);
if (!message || !*message)
return -1;
@@ -7041,7 +7174,7 @@ atcommand_chardropall(const int fd, struct map_session_data* sd,
for (i = 0; i < MAX_INVENTORY; i++) {
if (pl_sd->status.inventory[i].amount) {
if(pl_sd->status.inventory[i].equip != 0)
- pc_unequipitem(pl_sd, i, 0, BF_NORMAL);
+ pc_unequipitem(pl_sd, i, 3);
pc_dropitem(pl_sd, i, pl_sd->status.inventory[i].amount);
}
}
@@ -7064,6 +7197,7 @@ atcommand_storeall(const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
int i;
+ nullpo_retr(-1, sd);
if (storage_storageopen(sd) == 1) {
clif_displaymessage(fd, "run this command again..");
return 0;
@@ -7071,7 +7205,7 @@ atcommand_storeall(const int fd, struct map_session_data* sd,
for (i = 0; i < MAX_INVENTORY; i++) {
if (sd->status.inventory[i].amount) {
if(sd->status.inventory[i].equip != 0)
- pc_unequipitem(sd, i, 0, BF_NORMAL);
+ pc_unequipitem(sd, i, 3);
storage_storageadd(sd, i, sd->status.inventory[i].amount);
}
}
@@ -7092,10 +7226,11 @@ atcommand_charstoreall(const int fd, struct map_session_data* sd,
{
int i;
struct map_session_data *pl_sd = NULL;
+ nullpo_retr(-1, sd);
if (!message || !*message)
return -1;
- if((pl_sd=map_nick2sd((char *) message)) == NULL)
+ if((pl_sd=map_nick2sd((char *) message)) == NULL)
return -1;
if (storage_storageopen(pl_sd) == 1) {
@@ -7106,7 +7241,7 @@ atcommand_charstoreall(const int fd, struct map_session_data* sd,
for (i = 0; i < MAX_INVENTORY; i++) {
if (pl_sd->status.inventory[i].amount) {
if(pl_sd->status.inventory[i].equip != 0)
- pc_unequipitem(pl_sd, i, 0, BF_NORMAL);
+ pc_unequipitem(pl_sd, i, 3);
storage_storageadd(pl_sd, i, sd->status.inventory[i].amount);
}
}
@@ -7131,15 +7266,15 @@ atcommand_skillid(const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
int skillen = 0, idx = 0;
+ nullpo_retr(-1, sd);
if (!message || !*message)
return -1;
skillen = strlen(message);
while (skill_names[idx].id != 0) {
if ((strnicmp(skill_names[idx].name, message, skillen) == 0) ||
(strnicmp(skill_names[idx].desc, message, skillen) == 0)) {
- char output[255];
- sprintf(output, "skill %d: %s", skill_names[idx].id, skill_names[idx].desc);
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "skill %d: %s", skill_names[idx].id, skill_names[idx].desc);
+ clif_displaymessage(fd, atcmd_output);
}
idx++;
}
@@ -7161,10 +7296,11 @@ atcommand_useskill(const int fd, struct map_session_data* sd,
int skilllv;
int inf;
char target[255];
+ nullpo_retr(-1, sd);
if (!message || !*message)
return -1;
- if(sscanf(message, "%d %d %s", &skillnum, &skilllv, target) != 3) {
+ if(sscanf(message, "%d %d %99[^\n]", &skillnum, &skilllv, target) != 3) {
clif_displaymessage(fd, "Usage: @useskill <skillnum> <skillv> <target>");
return -1;
}
@@ -7197,7 +7333,8 @@ atcommand_skilltree(const int fd, struct map_session_data* sd,
int meets = 1, j, c=0, s=0;
struct pc_base_job s_class;
char target[255], *tbl;
- char output[255];
+ struct skill_tree_entry *ent;
+ nullpo_retr(-1, sd);
if (!message || !*message)
return -1;
@@ -7206,10 +7343,10 @@ atcommand_skilltree(const int fd, struct map_session_data* sd,
clif_displaymessage(fd, "Usage: @skilltree <skillnum> <target>");
return -1;
}
- if((pl_sd=map_nick2sd(target)) == NULL)
+ if((pl_sd=map_nick2sd(target)) == NULL)
return -1;
- s_class = pc_calc_base_job(pl_sd->status.class);
+ s_class = pc_calc_base_job(pl_sd->status.class_);
c = s_class.job;
s = s_class.upper;
@@ -7217,52 +7354,295 @@ atcommand_skilltree(const int fd, struct map_session_data* sd,
tbl = job_name(c);
- sprintf(output, "Player is using %s %s skill tree (%d basic points)",
- s_class.upper ? "upper" : "lower",
+ sprintf(atcmd_output, "Player is using %s %s skill tree (%d basic points)",
+ s_class.upper ? "upper" : "lower",
tbl, pc_checkskill(pl_sd, 1));
- clif_displaymessage(fd, output);
+ clif_displaymessage(fd, atcmd_output);
- for (j = 0; j < MAX_SKILL; j++) {
+ for (j = 0; skill_tree[s][c][j].id != 0; j++) {
if (skill_tree[s][c][j].id == skillnum) {
skillidx = j;
break;
}
}
-
+
if (skillidx == -1) {
- sprintf(output, "I do not believe the player can use that skill");
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "I do not believe the player can use that skill");
+ clif_displaymessage(fd, atcmd_output);
return 0;
}
- struct skill_tree_entry *ent = &skill_tree[s][c][skillidx];
+ ent = &skill_tree[s][c][skillidx];
- for(j=0;j<5;j++)
+ for(j=0;j<5;j++)
if( ent->need[j].id &&
- pc_checkskill(sd,ent->need[j].id) < ent->need[j].lv)
+ pc_checkskill(sd,ent->need[j].id) < ent->need[j].lv)
{
int idx = 0;
char *desc;
- while (skill_names[idx].id != 0 && skill_names[idx].id != ent->need[j].id)
+ while (skill_names[idx].id != 0 && skill_names[idx].id != ent->need[j].id)
idx++;
if (skill_names[idx].id == 0)
desc = "Unknown skill";
else
desc = skill_names[idx].desc;
- sprintf(output, "player requires level %d of skill %s",
+ sprintf(atcmd_output, "player requires level %d of skill %s",
ent->need[j].lv, desc);
- clif_displaymessage(fd, output);
+ clif_displaymessage(fd, atcmd_output);
meets = 0;
}
if (meets == 1) {
- sprintf(output, "I believe the player meets all the requirements for that skill");
- clif_displaymessage(fd, output);
+ sprintf(atcmd_output, "I believe the player meets all the requirements for that skill");
+ clif_displaymessage(fd, atcmd_output);
+ }
+
+ return 0;
+}
+
+/*==========================================
+ * @marry by [MouseJstr], fixed by Lupus
+ *
+ * Marry two players
+ *------------------------------------------
+ */
+int
+atcommand_marry(const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ struct map_session_data *pl_sd1 = NULL;
+ struct map_session_data *pl_sd2 = NULL;
+ char player1[255], player2[255];
+
+ nullpo_retr(-1, sd);
+
+ if (!message || !*message || sscanf(message, "%[^,],%[^\r\n]", player1, player2) != 2) {
+ clif_displaymessage(fd, "Usage: @marry <player1>,<player2>.");
+ return -1;
+ }
+
+ if((pl_sd1=map_nick2sd((char *) player1)) == NULL) {
+ sprintf(player2, "Cannot find player '%s' online", player1);
+ clif_displaymessage(fd, player2);
+ return -1;
+ }
+
+ if((pl_sd2=map_nick2sd((char *) player2)) == NULL) {
+ sprintf(player1, "Cannot find player '%s' online", player2);
+ clif_displaymessage(fd, player1);
+ return -1;
+ }
+
+ if (pc_marriage(pl_sd1, pl_sd2) == 0) {
+ clif_displaymessage(fd, "They are married.. wish them well");
+ clif_wedding_effect(&sd->bl); //wedding effect and music [Lupus]
+ return 0;
+ }
+ return -1;
+}
+
+/*==========================================
+ * @divorce by [MouseJstr], fixed by [Lupus]
+ *
+ * divorce two players
+ *------------------------------------------
+ */
+int
+atcommand_divorce(const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ struct map_session_data *pl_sd = NULL;
+
+ nullpo_retr(-1, sd);
+
+ if (!message || !*message || sscanf(message, "%[^\r\n]", atcmd_player_name) != 1) {
+ clif_displaymessage(fd, "Usage: @divorce <player>.");
+ return -1;
+ }
+
+ if((pl_sd=map_nick2sd((char *) atcmd_player_name)) != NULL) {
+ if (pc_divorce(pl_sd) != 0) {
+ sprintf(atcmd_output, "The divorce has failed.. Cannot find player '%s' or his(her) partner online.", atcmd_player_name);
+ clif_displaymessage(fd, atcmd_output);
+ return -1;
+ } else {
+ sprintf(atcmd_output, "'%s' and his(her) partner are now divorced.", atcmd_player_name);
+ clif_displaymessage(fd, atcmd_output);
+ return 0;
+ }
}
-
+ sprintf(atcmd_output, "Cannot find player '%s' online", atcmd_player_name);
+ clif_displaymessage(fd, atcmd_output);
+ return -1;
+}
+
+/*==========================================
+ * @rings by [MouseJstr]
+ *
+ * Give two players rings
+ *------------------------------------------
+ */
+int
+atcommand_rings(const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ struct item item_tmp;
+ int flag;
+
+ memset(&item_tmp, 0, sizeof(item_tmp));
+
+ item_tmp.nameid = 2634;
+ item_tmp.identify = 1;
+
+ if ((flag = pc_additem((struct map_session_data*)sd, &item_tmp, 1)))
+ clif_additem((struct map_session_data*)sd, 0, 0, flag);
+
+ item_tmp.nameid = 2635;
+ item_tmp.identify = 1;
+ if ((flag = pc_additem((struct map_session_data*)sd, &item_tmp, 1)))
+ clif_additem((struct map_session_data*)sd, 0, 0, flag);
+
+ clif_displaymessage(fd, "You have rings! Give them to the lovers.");
+
+ return 0;
+}
+
+#ifdef DMALLOC
+unsigned long dmark_;
+int
+atcommand_dmstart(const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ dmark_ = dmalloc_mark();
+
+ clif_displaymessage(fd, "debug mark set");
+
return 0;
}
+int
+atcommand_dmtick(const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ dmalloc_log_changed ( dmark_, 1, 0, 1 ) ;
+ dmark_ = dmalloc_mark();
+ clif_displaymessage(fd, "malloc changes logged");
+
+ return 0;
+}
+#endif
+
+/*==========================================
+ * @grind by [MouseJstr]
+ *------------------------------------------
+ */
+int
+atcommand_grind(const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ struct map_session_data *pl_sd = NULL;
+ int skillnum;
+ int inf;
+ char target[255];
+ nullpo_retr(-1, sd);
+
+ if (!message || !*message)
+ return -1;
+ if(sscanf(message, "%s", target) != 1) {
+ clif_displaymessage(fd, "Usage: @grind <target>");
+ return -1;
+ }
+ if((pl_sd=map_nick2sd(target)) == NULL)
+ return -1;
+
+ for (skillnum = 1; skillnum < 500; skillnum++) {
+ sd->status.sp = sd->status.max_sp;
+ atcommand_alive(fd, sd, command, message);
+
+ inf = skill_get_inf(skillnum);
+
+ if ((inf == 2) || (inf == 1))
+ skill_use_pos(sd, pl_sd->bl.x+5, pl_sd->bl.y+5, skillnum, 1);
+ else
+ skill_use_id(sd, pl_sd->bl.id, skillnum, 1);
+ }
+
+ return 0;
+}
+
+/*==========================================
+ * @grind2 by [MouseJstr]
+ *------------------------------------------
+ */
+int
+atcommand_grind2(const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ int i, x, y, id;
+
+ for (i = 1000; i <2000; i++) {
+ x = sd->bl.x + (rand() % 10 - 5);
+ y = sd->bl.y + (rand() % 10 - 5);
+ id = mob_once_spawn(sd, "this", x, y, "--ja--", i, 1, "");
+ }
+
+ return 0;
+}
+
+/*==========================================
+ * @changelook by [Celest]
+ *------------------------------------------
+ */
+int
+atcommand_changelook(const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ int i, j = 0, k = 0;
+ int pos[6] = { LOOK_HEAD_TOP,LOOK_HEAD_MID,LOOK_HEAD_BOTTOM,LOOK_WEAPON,LOOK_SHIELD,LOOK_SHOES };
+
+ if((i = sscanf(message, "%d %d", &j, &k)) < 1) {
+ clif_displaymessage(fd, "Usage: @changelook [<position>] <view id> -- [] = optional");
+ clif_displaymessage(fd, "Position: 1-Top 2-Middle 3-Bottom 4-Weapon 5-Shield");
+ return -1;
+ } else if (i == 2) {
+ if (j < 1) j = 1;
+ else if (j > 6) j = 6; // 6 = Shoes - for beta clients only perhaps
+ j = pos[j - 1];
+ } else if (i == 1) { // position not defined, use HEAD_TOP as default
+ k = j; // swap
+ j = LOOK_HEAD_TOP;
+ }
+
+ clif_changelook(&sd->bl,j,k);
+
+ return 0;
+}
+
+/*==========================================
+ *Turns on/off AutoLoot for a specific player
+ *------------------------------------------
+ *by Upa-Kun
+ */
+int
+atcommand_autoloot(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ nullpo_retr(-1, sd);
+ if (sd->autoloot)
+ {
+ sd->autoloot = 0;
+ clif_displaymessage(fd, "Autoloot is now off.");
+ }
+ else
+ {
+ sd->autoloot = 1;
+ clif_displaymessage(fd, "Autoloot is now on.");
+ }
+ return 0;
+}
+
+
/*==========================================
* It is made to rain.
*------------------------------------------
@@ -7273,13 +7653,16 @@ atcommand_rain(
const char* command, const char* message)
{
int effno = 0;
- effno = 161;
nullpo_retr(-1, sd);
- if (effno < 0 || map[sd->bl.m].flag.rain)
- return -1;
-
- map[sd->bl.m].flag.rain=1;
- clif_specialeffect(&sd->bl,effno,2);
+ effno = 161;
+ if (map[sd->bl.m].flag.rain) {
+ map[sd->bl.m].flag.rain=0;
+ clif_displaymessage(fd, "The rain has stopped.");
+ } else {
+ map[sd->bl.m].flag.rain=1;
+ clif_specialeffect(&sd->bl,effno,2);
+ clif_displaymessage(fd, "It is made to rain.");
+ }
return 0;
}
/*==========================================
@@ -7294,11 +7677,15 @@ atcommand_snow(
int effno = 0;
effno = 162;
nullpo_retr(-1, sd);
- if (effno < 0 || map[sd->bl.m].flag.snow)
- return -1;
+ if (map[sd->bl.m].flag.snow) {
+ map[sd->bl.m].flag.snow=0;
+ clif_displaymessage(fd, "Snow has stopped falling.");
+ } else {
+ map[sd->bl.m].flag.snow=1;
+ clif_specialeffect(&sd->bl,effno,2);
+ clif_displaymessage(fd, "It is made to snow.");
+ }
- map[sd->bl.m].flag.snow=1;
- clif_specialeffect(&sd->bl,effno,2);
return 0;
}
@@ -7314,11 +7701,14 @@ atcommand_sakura(
int effno = 0;
effno = 163;
nullpo_retr(-1, sd);
- if (effno < 0 || map[sd->bl.m].flag.sakura)
- return -1;
-
- map[sd->bl.m].flag.sakura=1;
- clif_specialeffect(&sd->bl,effno,2);
+ if (map[sd->bl.m].flag.sakura) {
+ map[sd->bl.m].flag.sakura=0;
+ clif_displaymessage(fd, "Cherry tree leaves is made to fall.");
+ } else {
+ map[sd->bl.m].flag.sakura=1;
+ clif_specialeffect(&sd->bl,effno,2);
+ clif_displaymessage(fd, "Cherry tree leaves is made to fall.");
+ }
return 0;
}
@@ -7334,11 +7724,14 @@ atcommand_fog(
int effno = 0;
effno = 233;
nullpo_retr(-1, sd);
- if (effno < 0 || map[sd->bl.m].flag.fog)
- return -1;
-
- map[sd->bl.m].flag.fog=1;
- clif_specialeffect(&sd->bl,effno,2);
+ if (map[sd->bl.m].flag.fog) {
+ map[sd->bl.m].flag.fog=0;
+ clif_displaymessage(fd, "The fog has gone.");
+ } else {
+ map[sd->bl.m].flag.fog=1;
+ clif_specialeffect(&sd->bl,effno,2);
+ clif_displaymessage(fd, "Fog hangs over.");
+ }
return 0;
}
@@ -7355,15 +7748,211 @@ atcommand_leaves(
int effno = 0;
effno = 333;
nullpo_retr(-1, sd);
- if (effno < 0 || map[sd->bl.m].flag.leaves)
+ if (map[sd->bl.m].flag.leaves) {
+ map[sd->bl.m].flag.leaves=0;
+ clif_displaymessage(fd, "Leaves no longer fall.");
+ } else {
+ map[sd->bl.m].flag.leaves=1;
+ clif_specialeffect(&sd->bl,effno,2);
+ clif_displaymessage(fd, "Fallen leaves fall.");
+ }
+
+ return 0;
+}
+
+/*==========================================
+ * Clearing Weather Effects by Dexity
+ *------------------------------------------
+ */
+int
+atcommand_clearweather(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ //int effno = 0;
+ nullpo_retr(-1, sd);
+ map[sd->bl.m].flag.rain=0;
+ map[sd->bl.m].flag.snow=0;
+ map[sd->bl.m].flag.sakura=0;
+ map[sd->bl.m].flag.fog=0;
+ map[sd->bl.m].flag.leaves=0;
+ //clif_specialeffect(&sd->bl,effno,2); // not required. [celest]
+ return 0;
+}
+
+/*===============================================================
+ * Sound Command - plays a sound for everyone! [Codemaster]
+ *---------------------------------------------------------------
+ */
+int
+atcommand_sound(
+ const int fd, struct map_session_data *sd,
+ const char *command, const char *message)
+{
+ char sound_file[100];
+
+ if(!message || !*message || sscanf(message, "%99[^\n]", sound_file) < 1) {
+ clif_displaymessage(fd, "Please, enter a sound filename. (usage: @sound <filename>)");
+ return -1;
+ }
+
+ memset(sound_file, '\0', sizeof(sound_file));
+ if(sscanf(message, "%99[^\n]", sound_file) < 1)
+ return -1;
+
+ if(strstr(sound_file, ".wav") == NULL)
+ strcat(sound_file, ".wav");
+
+ clif_soundeffectall(&sd->bl, sound_file,0);
+
+ return 0;
+}
+
+/*==========================================
+ * MOB Search
+ *------------------------------------------
+ */
+int
+atcommand_mobsearch(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ char mob_name[100];
+ int mob_id,map_id = 0;
+
+ nullpo_retr(-1, sd);
+
+ if (sscanf(message, "%99[^\n]", mob_name) < 0)
+ return -1;
+
+ if ((mob_id = atoi(mob_name)) == 0)
+ mob_id = mobdb_searchname(mob_name);
+ if(mob_id !=-1 && (mob_id <= 1000 || mob_id >= 2000)){
+ snprintf(atcmd_output, sizeof atcmd_output, "Invalid mob id %s!",mob_name);
+ clif_displaymessage(fd, atcmd_output);
+ return 0;
+ }
+ if(mob_id == atoi(mob_name) && mob_db[mob_id].jname)
+ strcpy(mob_name,mob_db[mob_id].jname); // --ja--
+// strcpy(mob_name,mob_db[mob_id].name); // --en--
+
+ map_id = sd->bl.m;
+
+ snprintf(atcmd_output, sizeof atcmd_output, "Mob Search... %s %s",
+ mob_name, sd->mapname);
+ clif_displaymessage(fd, atcmd_output);
+
+ map_foreachinarea(atmobsearch_sub, map_id, 0, 0,
+ map[map_id].xs, map[map_id].ys, BL_MOB, mob_id, fd);
+
+ atmobsearch_sub(&sd->bl,0); // ”Ô†ƒŠƒZƒbƒg
+
+ return 0;
+}
+/*==========================================
+ * ƒhƒƒbƒvƒAƒCƒeƒ€‚Ì‘|œ
+ *------------------------------------------
+ */
+int
+atcommand_cleanmap(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ int i=0;
+ map_foreachinarea(atcommand_cleanmap_sub,sd->bl.m,
+ sd->bl.x-AREA_SIZE*2,sd->bl.y-AREA_SIZE*2,
+ sd->bl.x+AREA_SIZE*2,sd->bl.y+AREA_SIZE*2,
+ BL_ITEM,sd,&i);
+ clif_displaymessage(fd, "All dropped items have been cleaned up.");
+ return 0;
+}
+
+/*==========================================
+ * NPC/PET‚ɘb‚³‚¹‚é
+ *------------------------------------------
+ */
+int
+atcommand_npctalk(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ char name[100],mes[100];
+ struct npc_data *nd;
+
+ if (sscanf(message, "%s %99[^\n]", name, mes) < 2)
+ return -1;
+
+ if (!(nd = npc_name2id(name)))
+ return -1;
+
+ clif_message(&nd->bl, mes);
+ return 0;
+}
+int
+atcommand_pettalk(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ char mes[100],temp[100];
+ struct pet_data *pd;
+
+ nullpo_retr(-1, sd);
+
+ if(!sd->status.pet_id || !(pd=sd->pd))
return -1;
- map[sd->bl.m].flag.leaves=1;
- clif_specialeffect(&sd->bl,effno,2);
+ if (sscanf(message, "%99[^\n]", mes) < 1)
+ return -1;
+
+ snprintf(temp, sizeof temp ,"%s : %s",sd->pet.name,mes);
+ clif_message(&pd->bl, temp);
+
return 0;
}
+
/*==========================================
- *
+ * @users
+ * ƒT[ƒo[“à‚Ìl”ƒ}ƒbƒv‚ð•\ަ‚³‚¹‚é
+ * Žè”²‚«‚Ì‚½‚߉˜‚­‚È‚Á‚Ä‚¢‚é‚͎̂d—l‚Å‚·B
+ *------------------------------------------
+ */
+
+static struct dbt *users_db;
+static int users_all;
+
+static int atcommand_users_sub1(struct map_session_data* sd,va_list va) {
+ int users = (int)strdb_search(users_db,sd->mapname) + 1;
+ users_all++;
+ strdb_insert(users_db,sd->mapname,(void *)users);
+ return 0;
+}
+
+static int atcommand_users_sub2(void* key,void* val,va_list va) {
+ char buf[256];
+ struct map_session_data* sd = va_arg(va,struct map_session_data*);
+ sprintf(buf,"%s : %d (%d%%)",(char *)key,(int)val,(int)val * 100 / users_all);
+ clif_displaymessage(sd->fd,buf);
+ return 0;
+}
+
+int
+atcommand_users(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ char buf[256];
+ users_all = 0;
+ users_db = strdb_init(24);
+ clif_foreachclient(atcommand_users_sub1);
+ strdb_foreach(users_db,atcommand_users_sub2,sd);
+ sprintf(buf,"all : %d",users_all);
+ clif_displaymessage(fd,buf);
+ strdb_final(users_db,NULL);
+ return 0;
+}
+
+/*==========================================
+ *
*------------------------------------------
*/
int
@@ -7378,14 +7967,14 @@ atcommand_summon(
int id = 0;
struct mob_data *md;
unsigned int tick=gettick();
-
+
nullpo_retr(-1, sd);
if (!message || !*message)
return -1;
if (sscanf(message, "%99s", name) < 1)
return -1;
-
+
if ((mob_id = atoi(name)) == 0)
mob_id = mobdb_searchname(name);
if(mob_id == 0)
@@ -7398,7 +7987,7 @@ atcommand_summon(
if((md=(struct mob_data *)map_id2bl(id))){
md->master_id=sd->bl.id;
md->state.special_mob_ai=1;
- md->mode=mob_db[md->class].mode|0x04;
+ md->mode=mob_db[md->class_].mode|0x04;
md->deletetimer=add_timer(tick+60000,mob_timer_delete,id,0);
clif_misceffect2(&md->bl,344);
}
@@ -7424,9 +8013,10 @@ atcommand_adjcmdlvl(
{
int i, newlev;
char cmd[100];
+ nullpo_retr(-1, sd);
if (!message || !*message || sscanf(message, "%d %s", &newlev, cmd) != 2) {
- clif_displaymessage(fd, "usage: @adjcmdlvl <lvl> <command>.");
+ clif_displaymessage(fd, "Usage: @adjcmdlvl <lvl> <command>.");
return -1;
}
@@ -7458,13 +8048,14 @@ atcommand_adjgmlvl(
int newlev;
char user[100];
struct map_session_data *pl_sd;
+ nullpo_retr(-1, sd);
if (!message || !*message || sscanf(message, "%d %[^\r\n]", &newlev, user) != 2) {
- clif_displaymessage(fd, "usage: @adjgmlvl <lvl> <user>.");
+ clif_displaymessage(fd, "Usage: @adjgmlvl <lvl> <user>.");
return -1;
}
- if((pl_sd=map_nick2sd((char *) user)) == NULL)
+ if((pl_sd=map_nick2sd((char *) user)) == NULL)
return -1;
pc_set_gm_level(pl_sd->status.account_id, newlev);
@@ -7478,7 +8069,7 @@ atcommand_adjgmlvl(
*
* Open a trade window with a remote player
*
- * If I have to jump to a remote player one more time, I am
+ * If I have to jump to a remote player one more time, I am
* gonna scream!
*------------------------------------------
*/
@@ -7488,6 +8079,7 @@ atcommand_trade(
const char* command, const char* message)
{
struct map_session_data *pl_sd = NULL;
+ nullpo_retr(-1, sd);
if (!message || !*message)
return -1;
@@ -7509,13 +8101,14 @@ atcommand_setbattleflag(
const char* command, const char* message)
{
char flag[128], value[128];
+ nullpo_retr(-1, sd);
if (!message || !*message || sscanf(message, "%s %s", flag, value) != 2) {
- clif_displaymessage(fd, "usage: @setbattleflag <flag> <value>.");
+ clif_displaymessage(fd, "Usage: @setbattleflag <flag> <value>.");
return -1;
}
- if (battle_set_value(flag, value) == 0)
+ if (battle_set_value(flag, value) == 0)
clif_displaymessage(fd, "unknown battle_config flag");
else
clif_displaymessage(fd, "battle_config set as requested");
@@ -7533,13 +8126,14 @@ int atcommand_unmute(
const char* command, const char* message)
{
struct map_session_data *pl_sd = NULL;
+ nullpo_retr(-1, sd);
if (!message || !*message)
return -1;
if((pl_sd=map_nick2sd((char *) message)) != NULL) {
if(pl_sd->sc_data[SC_NOCHAT].timer!=-1) {
pl_sd->status.manner = 0; // have to set to 0 first [celest]
- skill_status_change_end(&pl_sd->bl,SC_NOCHAT,-1);
+ status_change_end(&pl_sd->bl,SC_NOCHAT,-1);
clif_displaymessage(sd->fd,"Player unmuted");
}
else
@@ -7558,9 +8152,9 @@ atcommand_uptime(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- char output[200];
long seconds = 0, day = 24*60*60, hour = 60*60,
minute = 60, days = 0, hours = 0, minutes = 0;
+ nullpo_retr(-1, sd);
seconds = (gettick()-ticks)/CLOCKS_PER_SEC;
days = seconds/day;
@@ -7569,9 +8163,11 @@ atcommand_uptime(
seconds -= (seconds/hour>0)?(seconds/hour)*hour:0;
minutes = seconds/minute;
seconds -= (seconds/minute>0)?(seconds/minute)*minute:0;
-
- snprintf(output, sizeof(output), msg_table[245], days, hours, minutes, seconds);
- clif_displaymessage(fd,output);
+
+ snprintf(atcmd_output, sizeof(atcmd_output), msg_table[245], days, hours, minutes, seconds);
+
+ clif_displaymessage(fd,atcmd_output);
+
return 0;
}
@@ -7586,7 +8182,8 @@ atcommand_changesex(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- chrif_changesex(sd->status.account_id, ((sd->status.sex+1)%2));
+ nullpo_retr(-1, sd);
+ chrif_char_ask_name(sd->status.account_id,sd->status.name, 5,0,0,0,0,0,0);
return 0;
}
@@ -7599,18 +8196,18 @@ int atcommand_mute(
const char* command, const char* message)
{
struct map_session_data *pl_sd = NULL;
- char character[100];
int manner;
+ nullpo_retr(-1, sd);
- if (!message || !*message || sscanf(message, "%d %99[^\n]", &manner, character) < 1) {
- clif_displaymessage(fd, "usage: @mute <time> <character name>.");
+ if (!message || !*message || sscanf(message, "%d %99[^\n]", &manner, atcmd_player_name) < 1) {
+ clif_displaymessage(fd, "Usage: @mute <time> <character name>.");
return -1;
}
- if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if ((pl_sd = map_nick2sd(atcmd_player_name)) != NULL) {
pl_sd->status.manner -= manner;
if(pl_sd->status.manner < 0)
- skill_status_change_start(&pl_sd->bl,SC_NOCHAT,0,0,0,0,0,0);
+ status_change_start(&pl_sd->bl,SC_NOCHAT,0,0,0,0,0,0);
}
else {
clif_displaymessage(fd, msg_table[3]); // Character not found.
@@ -7628,9 +8225,9 @@ int atcommand_refresh(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
-
nullpo_retr(-1, sd);
- pc_setpos(sd, sd->mapname, sd->bl.x, sd->bl.y, 3);
+ //pc_setpos(sd, sd->mapname, sd->bl.x, sd->bl.y, 3);
+ clif_refresh(sd);
return 0;
}
@@ -7647,7 +8244,7 @@ atcommand_petid(const int fd, struct map_session_data* sd,
char temp0[100];
char temp1[100];
int cnt = 0, i = 0;
-
+
nullpo_retr(-1, sd);
if (!message || !*message)
@@ -7663,7 +8260,7 @@ atcommand_petid(const int fd, struct map_session_data* sd,
strcpy(temp0,pet_db[i].jname);
strcpy(temp0, estr_lower(temp1));
if (strstr(temp1, searchtext) || strstr(temp0, searchtext) ) {
- snprintf(temp0, sizeof(temp0), "ID: %i -- Name: %s", pet_db[i].class,
+ snprintf(temp0, sizeof(temp0), "ID: %i -- Name: %s", pet_db[i].class_,
pet_db[i].jname);
if (cnt >= 100) { // Only if there are custom pets
clif_displaymessage(fd, "Be more specific, can't send more than"
@@ -7690,15 +8287,17 @@ atcommand_identify(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- nullpo_retr(-1, sd);
int i,num;
+
+ nullpo_retr(-1, sd);
+
for(i=num=0;i<MAX_INVENTORY;i++){
if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].identify!=1){
num++;
}
}
if (num > 0) {
- clif_item_identify_list(sd);
+ clif_item_identify_list(sd);
} else {
clif_displaymessage(fd,"There are no items to appraise.");
}
@@ -7706,7 +8305,7 @@ atcommand_identify(
}
/*==========================================
- * @gmotd (Global MOTD)
+ * @gmotd (Global MOTD)
* by davidsiaw :P
*------------------------------------------
*/
@@ -7717,6 +8316,7 @@ atcommand_gmotd(
{
char buf[256];
FILE *fp;
+ nullpo_retr(-1, sd);
if( (fp = fopen(motd_txt, "r"))!=NULL){
while (fgets(buf, 250, fp) != NULL){
int i;
@@ -7744,10 +8344,632 @@ int atcommand_misceffect(
if (sscanf(message, "%d", &effect) < 1)
return -1;
clif_misceffect(&sd->bl,effect);
-
+
return 0;
}
+int charid2sessionid(int charid)
+{
+ int i;
+ int session_id=0;
+ struct map_session_data *pl_sd = NULL;
+
+ for(i=0;i<fd_max;i++){
+ if(session[i] && (pl_sd= (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth){
+ if (pl_sd->status.char_id==charid) { session_id = i; break; }
+ }
+ }
+
+ return session_id;
+}
+
+int accountid2sessionid(int accountid)
+{
+ int i;
+ int session_id=0;
+ struct map_session_data *pl_sd = NULL;
+
+ for(i=0;i<fd_max;i++){
+ if(session[i] && (pl_sd= (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth){
+ if (pl_sd->status.account_id==accountid) { session_id = i; break; }
+ }
+ }
+
+ return session_id;
+}
+
+
+/*==========================================
+ * Jump to a player by PID number
+ * Original by Dino9021
+ * Added in by nsstrunks
+ *------------------------------------------
+ */
+
+int atcommand_jumptoid(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ int cid=0;
+ int session_id=0;
+ struct map_session_data *pl_sd;
+
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+
+ if (!message || (cid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
+ clif_displaymessage(fd, "Please, enter a player CID (usage: @jumptoid/@warptoid/@gotoid <char id>).");
+ return -1;
+ }
+
+ cid=atoi(message);
+
+ if ((session_id=charid2sessionid(cid))!=0)
+ {
+ if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) {
+ if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
+ clif_displaymessage(fd, msg_table[247]);
+ return -1;
+ }
+ if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
+ clif_displaymessage(fd, msg_table[248]);
+ return -1;
+ }
+ pc_setpos(sd, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y, 3);
+ sprintf(atcmd_output, msg_table[4], pl_sd->status.name); // Jump to %s
+ clif_displaymessage(fd, atcmd_output);
+ } else {
+ clif_displaymessage(fd, msg_table[154]); // Character not found.
+ return -1;
+ }
+ }
+ else
+ {
+ clif_displaymessage(fd,msg_table[3]);
+ }
+ //printf("Session_id = %d, cid = %d\n",session_id,cid);
+
+ return 0;
+}
+
+/*==========================================
+ * Jump to a player by PID number
+ * Original by Dino9021
+ * Added in by nsstrunks
+ *------------------------------------------
+ */
+
+int atcommand_jumptoid2(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ int aid=0;
+ int session_id=0;
+ struct map_session_data *pl_sd;
+
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+
+ if (!message || (aid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
+ clif_displaymessage(fd, "Please, enter a player AID (usage: @jumptoid/@warptoid/@gotoid <account id>).");
+ return -1;
+ }
+
+ aid=atoi(message);
+
+ if ((session_id=accountid2sessionid(aid))!=0)
+ {
+ if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) {
+ if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
+ clif_displaymessage(fd, msg_table[247]);
+ return -1;
+ }
+ if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
+ clif_displaymessage(fd, msg_table[248]);
+ return -1;
+ }
+ pc_setpos(sd, pl_sd->mapname, pl_sd->bl.x, pl_sd->bl.y, 3);
+ sprintf(atcmd_output, msg_table[4], pl_sd->status.name); // Jump to %s
+ clif_displaymessage(fd, atcmd_output);
+ } else {
+ clif_displaymessage(fd, msg_table[154]); // Character not found.
+ return -1;
+ }
+ }
+ else
+ {
+ clif_displaymessage(fd,msg_table[3]);
+ }
+ //printf("Session_id = %d, aid = %d\n",session_id,aid);
+
+ return 0;
+}
+
+/*==========================================
+ * Recall a player by PID number
+ * Original by Dino9021
+ * Added in by nsstrunks
+ *------------------------------------------
+ */
+int atcommand_recallid(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ int cid=0;
+ int session_id=0;
+ struct map_session_data *pl_sd;
+
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+
+ if (!message || (cid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
+ clif_displaymessage(fd, "Please, enter a player CID (usage: @recallid <char id>).");
+ return -1;
+ }
+
+ cid=atoi(message);
+
+ if ((session_id=charid2sessionid(cid))!=0)
+ {
+ if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) {
+ if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can recall only lower or same level
+ if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
+ clif_displaymessage(fd, msg_table[247]);
+ return -1;
+ }
+ if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
+ clif_displaymessage(fd, msg_table[248]);
+ return -1;
+ }
+ pc_setpos(pl_sd, sd->mapname, sd->bl.x, sd->bl.y, 2);
+ sprintf(atcmd_output, msg_table[46], pl_sd->status.name); // Jump to %s
+ clif_displaymessage(fd, atcmd_output);
+ } else {
+ clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[154]); // Character not found.
+ return -1;
+ }
+ }
+ else
+ {
+ clif_displaymessage(fd,msg_table[3]);
+ }
+ //printf("Session_id = %d, cid = %d\n",session_id,cid);
+
+ return 0;
+}
+
+/*==========================================
+ * Recall a player by PID number
+ * Original by Dino9021
+ * Added in by nsstrunks
+ *------------------------------------------
+ */
+int atcommand_recallid2(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ int aid=0;
+ int session_id=0;
+ struct map_session_data *pl_sd;
+
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+
+ if (!message || (aid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
+ clif_displaymessage(fd, "Please, enter a player AID (usage: @recallid2 <account id>).");
+ return -1;
+ }
+
+ aid=atoi(message);
+
+ if ((session_id=accountid2sessionid(aid))!=0)
+ {
+ if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) {
+ if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can recall only lower or same level
+ if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
+ clif_displaymessage(fd, msg_table[247]);
+ return -1;
+ }
+ if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
+ clif_displaymessage(fd, msg_table[248]);
+ return -1;
+ }
+ pc_setpos(pl_sd, sd->mapname, sd->bl.x, sd->bl.y, 2);
+ sprintf(atcmd_output, msg_table[46], pl_sd->status.name); // Jump to %s
+ clif_displaymessage(fd, atcmd_output);
+ } else {
+ clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[154]); // Character not found.
+ return -1;
+ }
+ }
+ else
+ {
+ clif_displaymessage(fd,msg_table[3]);
+ }
+ //printf("Session_id = %d, aid = %d\n",session_id,aid);
+
+ return 0;
+}
+
+/*==========================================
+ * Kick a player by PID number
+ * Original by Dino9021
+ * Added in by nsstrunks
+ *------------------------------------------
+ */
+int atcommand_kickid(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ struct map_session_data *pl_sd;
+ int cid=0;
+ int session_id=0;
+
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+
+ if (!message || (cid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
+ clif_displaymessage(fd, "Please, enter a player CID (usage: @kickid <char id>).");
+ return -1;
+ }
+
+ cid=atoi(message);
+
+ if ((session_id=charid2sessionid(cid))!=0)
+ {
+ if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) {
+ if (pc_isGM(sd) >= pc_isGM(pl_sd)) // you can kick only lower or same gm level
+ clif_GM_kick(sd, pl_sd, 1);
+ else {
+ clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[3]); // Character not found.
+ return -1;
+ }
+
+ }
+ else
+ {
+ clif_displaymessage(fd,msg_table[3]);
+ }
+ //printf("Session_id = %d, cid = %d\n",session_id,cid);
+
+ return 0;
+}
+
+/*==========================================
+ * Kick a player by PID number
+ * Original by Dino9021
+ * Added in by nsstrunks
+ *------------------------------------------
+ */
+int atcommand_kickid2(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ struct map_session_data *pl_sd;
+ int aid=0;
+ int session_id=0;
+
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+
+ if (!message || (aid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
+ clif_displaymessage(fd, "Please, enter a player AID (usage: @kickid2 <account id>).");
+ return -1;
+ }
+
+ aid=atoi(message);
+
+ if ((session_id=accountid2sessionid(aid))!=0)
+ {
+ if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) {
+ if (pc_isGM(sd) >= pc_isGM(pl_sd)) // you can kick only lower or same gm level
+ clif_GM_kick(sd, pl_sd, 1);
+ else {
+ clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[3]); // Character not found.
+ return -1;
+ }
+
+ }
+ else
+ {
+ clif_displaymessage(fd,msg_table[3]);
+ }
+ //printf("Session_id = %d, aid = %d\n",session_id,aid);
+
+ return 0;
+}
+
+/*==========================================
+ * Revive a player by PID number
+ * Original by Dino9021
+ * Added in by nsstrunks
+ *------------------------------------------
+ */
+int atcommand_reviveid(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ int cid=0;
+ int session_id=0;
+ struct map_session_data *pl_sd;
+
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+
+ if (!message || (cid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
+ clif_displaymessage(fd, "Please, enter a player CID (usage: @reviveid <char id>).");
+ return -1;
+ }
+
+ cid=atoi(message);
+
+ if ((session_id=charid2sessionid(cid))!=0)
+ {
+ if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) {
+ pl_sd->status.hp = pl_sd->status.max_hp;
+ pc_setstand(pl_sd);
+ if (battle_config.pc_invincible_time > 0)
+ pc_setinvincibletimer(sd, battle_config.pc_invincible_time);
+ clif_updatestatus(pl_sd, SP_HP);
+ clif_updatestatus(pl_sd, SP_SP);
+ clif_resurrection(&pl_sd->bl, 1);
+ clif_displaymessage(fd, msg_table[51]); // Character revived.
+ } else {
+ clif_displaymessage(fd, msg_table[3]); // Character not found.
+ return -1;
+ }
+
+ }
+ else
+ {
+ clif_displaymessage(fd,msg_table[3]);
+ }
+ //printf("Session_id = %d, cid = %d\n",session_id,cid);
+
+
+ return 0;
+}
+
+/*==========================================
+ * Revive a player by PID number
+ * Original by Dino9021
+ * Added in by nsstrunks
+ *------------------------------------------
+ */
+int atcommand_reviveid2(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ int aid=0;
+ int session_id=0;
+ struct map_session_data *pl_sd;
+
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+
+ if (!message || (aid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
+ clif_displaymessage(fd, "Please, enter a player AID (usage: @reviveid2 <account id>).");
+ return -1;
+ }
+
+ aid=atoi(message);
+
+ if ((session_id=accountid2sessionid(aid))!=0)
+ {
+ if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) {
+ pl_sd->status.hp = pl_sd->status.max_hp;
+ pc_setstand(pl_sd);
+ if (battle_config.pc_invincible_time > 0)
+ pc_setinvincibletimer(sd, battle_config.pc_invincible_time);
+ clif_updatestatus(pl_sd, SP_HP);
+ clif_updatestatus(pl_sd, SP_SP);
+ clif_resurrection(&pl_sd->bl, 1);
+ clif_displaymessage(fd, msg_table[51]); // Character revived.
+ } else {
+ clif_displaymessage(fd, msg_table[3]); // Character not found.
+ return -1;
+ }
+
+ }
+ else
+ {
+ clif_displaymessage(fd,msg_table[3]);
+ }
+ //printf("Session_id = %d, aid = %d\n",session_id,aid);
+
+
+ return 0;
+}
+
+/*==========================================
+ * Kill a player by PID number
+ * Original by Dino9021
+ * Added in by nsstrunks
+ *------------------------------------------
+ */
+int atcommand_killid(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ int cid=0;
+ int session_id=0;
+ struct map_session_data *pl_sd;
+
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+
+ if (!message || (cid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
+ clif_displaymessage(fd, "Please, enter a player CID (usage: @killid <char id>).");
+ return -1;
+ }
+
+ cid=atoi(message);
+
+ if ((session_id=charid2sessionid(cid))!=0)
+ {
+ if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) {
+ if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can kill only lower or same level
+ pc_damage(NULL, pl_sd, pl_sd->status.hp + 1);
+ clif_displaymessage(fd, msg_table[14]); // Character killed.
+ } else {
+ clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[3]); // Character not found.
+ return -1;
+ }
+
+ }
+ else
+ {
+ clif_displaymessage(fd,msg_table[3]);
+ }
+ //printf("Session_id = %d, cid = %d\n",session_id,cid);
+
+ return 0;
+}
+
+/*==========================================
+ * Kill a player by PID number
+ * Original by Dino9021
+ * Added in by nsstrunks
+ *------------------------------------------
+ */
+int atcommand_killid2(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ int aid=0;
+ int session_id=0;
+ struct map_session_data *pl_sd;
+
+ memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
+
+ if (!message || (aid = atoi(message)) == 0 || !*message || sscanf(message, "%99[^\n]", atcmd_player_name) < 1) {
+ clif_displaymessage(fd, "Please, enter a player AID (usage: @killid2 <account id>).");
+ return -1;
+ }
+
+ aid=atoi(message);
+
+ if ((session_id=accountid2sessionid(aid))!=0)
+ {
+ if ((pl_sd = (struct map_session_data *) session[session_id]->session_data) != NULL) {
+ if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can kill only lower or same level
+ pc_damage(NULL, pl_sd, pl_sd->status.hp + 1);
+ clif_displaymessage(fd, msg_table[14]); // Character killed.
+ } else {
+ clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[3]); // Character not found.
+ return -1;
+ }
+
+ }
+ else
+ {
+ clif_displaymessage(fd,msg_table[3]);
+ }
+ //printf("Session_id = %d, aid = %d\n",session_id,aid);
+
+ return 0;
+}
+
+/*==========================================
+ * Make a player killable, by PID
+ * Original by Dino9021
+ * Added in by nsstrunks
+ *------------------------------------------
+ */
+int
+atcommand_charkillableid(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ struct map_session_data *pl_sd = NULL;
+ int cid=0;
+ int session_id=0;
+
+ if (!message || (cid = atoi(message)) == 0 || !*message)
+ return -1;
+
+ cid=atoi(message);
+
+ if ((session_id=charid2sessionid(cid))!=0)
+ {
+ if((pl_sd= (struct map_session_data *) session[session_id]->session_data) == NULL)
+ return -1;
+
+ pl_sd->special_state.killable = !pl_sd->special_state.killable;
+
+ if(pl_sd->special_state.killable)
+ clif_displaymessage(fd, "The player is now killable");
+ else
+ clif_displaymessage(fd, "The player is no longer killable");
+ }
+ else
+ {
+ clif_displaymessage(fd,msg_table[3]);
+ }
+ //printf("Session_id = %d, cid = %d\n",session_id,cid);
+ return 0;
+}
+
+
+/*==========================================
+ * Make a player killable, by PID
+ * Original by Dino9021
+ * Added in by nsstrunks
+ *------------------------------------------
+ */
+int
+atcommand_charkillableid2(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ struct map_session_data *pl_sd = NULL;
+ int aid=0;
+ int session_id=0;
+
+ if (!message || (aid = atoi(message)) == 0 || !*message)
+ return -1;
+
+ aid=atoi(message);
+
+ if ((session_id=accountid2sessionid(aid))!=0)
+ {
+ if((pl_sd= (struct map_session_data *) session[session_id]->session_data) == NULL)
+ return -1;
+
+ pl_sd->special_state.killable = !pl_sd->special_state.killable;
+
+ if(pl_sd->special_state.killable)
+ clif_displaymessage(fd, "The player is now killable");
+ else
+ clif_displaymessage(fd, "The player is no longer killable");
+ }
+ else
+ {
+ clif_displaymessage(fd,msg_table[3]);
+ }
+ //printf("Session_id = %d, aid = %d\n",session_id,aid);
+ return 0;
+}
+
#ifndef TXT_ONLY /* Begin SQL-Only commands */
/*==========================================
@@ -7767,7 +8989,7 @@ int atcommand_listmail(
mail_check(sd,3);
else if(strlen(command)==9)
mail_check(sd,2);
- else
+ else
mail_check(sd,1);
return 0;
}
@@ -7818,7 +9040,7 @@ int atcommand_sendmail(
if(strlen(command)==17)
mail_send(sd,name,text,1);
- else
+ else
mail_send(sd,name,text,0);
return 0;
@@ -7837,8 +9059,171 @@ int atcommand_refreshonline(
nullpo_retr(-1, sd);
char_online_check();
-
+
return 0;
}
#endif /* end sql only */
+
+/*==========================================
+ * Show Monster DB Info v 1.0
+ * originally by [Lupus] eAthena
+ *------------------------------------------
+ */
+int atcommand_mobinfo(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ unsigned char msize[3][7] = {"Small", "Medium", "Large"};
+ unsigned char mrace[12][11] = {"Formless", "Undead", "Beast", "Plant", "Insect", "Fish", "Demon", "Demi-Human", "Angel", "Dragon", "Boss", "Non-Boss"};
+ unsigned char melement[11][8] = {"None", "Neutral", "Water", "Earth", "Fire", "Wind", "Poison", "Holy", "Dark", "Ghost", "Undead"};
+ char atcmd_output2[200];
+ struct item_data *item_data;
+ struct mob_db *mob;
+ int mob_id;
+ int i, j;
+
+ memset(atcmd_output, '\0', sizeof(atcmd_output));
+ memset(atcmd_output2, '\0', sizeof(atcmd_output2));
+
+ if (!message || !*message) {
+ clif_displaymessage(fd, "Please, enter a Monster/NPC name/id (usage: @mobinfo <monster_name_or_monster_ID>).");
+ return -1;
+ }
+
+ // If monster identifier/name argument is a name
+ if ((mob_id = mobdb_searchname(message)) == 0) // check name first (to avoid possible name begining by a number)
+ mob_id = mobdb_checkid(atoi(message));
+
+ if (mob_id == 0) {
+ clif_displaymessage(fd, msg_table[40]); // Invalid monster ID or name.
+ return -1;
+ }
+
+ mob = &mob_db[mob_id];
+
+ // stats
+ if (mob->mexp)
+ sprintf(atcmd_output, "Monster (MVP): '%s'/'%s' (%d)", mob->name, mob->jname, mob_id);
+ else
+ sprintf(atcmd_output, "Monster: '%s'/'%s' (%d)", mob->name, mob->jname, mob_id);
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, " Level:%d HP:%d SP:%d Base EXP:%d Job EXP:%d", mob->lv, mob->max_hp, mob->max_sp, mob->base_exp, mob->job_exp);
+ clif_displaymessage(fd, atcmd_output);
+ sprintf(atcmd_output, " DEF:%d MDEF:%d STR:%d AGI:%d VIT:%d INT:%d DEX:%d LUK:%d", mob->def, mob->mdef, mob->str, mob->agi, mob->vit, mob->int_, mob->dex, mob->luk);
+ clif_displaymessage(fd, atcmd_output);
+ if (mob->element < 20) {
+ //Element - None, Level 0
+ i = 0;
+ j = 0;
+ } else {
+ i = mob->element % 20 + 1;
+ j = mob->element / 20;
+ }
+ sprintf(atcmd_output, " ATK:%d~%d Range:%d~%d~%d Size:%s Race: %s Element: %s (Lv:%d)", mob->atk1, mob->atk2, mob->range, mob->range2 , mob->range3, msize[mob->size], mrace[mob->race], melement[i], j);
+ clif_displaymessage(fd, atcmd_output);
+ // drops
+ clif_displaymessage(fd, " Drops:");
+ strcpy(atcmd_output, " ");
+ j = 0;
+ for (i = 0; i < 10; i++) {
+ if (mob->dropitem[i].nameid <= 0 || (item_data = itemdb_search(mob->dropitem[i].nameid)) == NULL)
+ continue;
+ if (mob->dropitem[i].p > 0) {
+ sprintf(atcmd_output2, " - %s %02.02f%%", item_data->name, (float)mob->dropitem[i].p / 100);
+ strcat(atcmd_output, atcmd_output2);
+ if (++j % 3 == 0) {
+ clif_displaymessage(fd, atcmd_output);
+ strcpy(atcmd_output, " ");
+ }
+ }
+ }
+ if (j == 0)
+ clif_displaymessage(fd, "This monster has no drop.");
+ else if (j % 3 != 0)
+ clif_displaymessage(fd, atcmd_output);
+ // mvp
+ if (mob->mexp) {
+ sprintf(atcmd_output, " MVP Bonus EXP:%d %02.02f%%", mob->mexp, (float)mob->mexpper / 100);
+ clif_displaymessage(fd, atcmd_output);
+ strcpy(atcmd_output, " MVP Items:");
+ j = 0;
+ for (i = 0; i < 3; i++) {
+ if (mob->mvpitem[i].nameid <= 0 || (item_data = itemdb_search(mob->mvpitem[i].nameid)) == NULL)
+ continue;
+ 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);
+ else
+ sprintf(atcmd_output2, " - %s %02.02f%%", item_data->name, (float)mob->mvpitem[i].p / 100);
+ strcat(atcmd_output, atcmd_output2);
+ }
+ }
+ if (j == 0)
+ clif_displaymessage(fd, "This monster has no MVP drop.");
+ else
+ clif_displaymessage(fd, atcmd_output);
+ }
+
+ return 0;
+}
+
+/*==========================================
+ * @adopt by [Veider]
+ *
+ * adopt a novice
+ *------------------------------------------
+ */
+int
+atcommand_adopt(const int fd, struct map_session_data* sd,
+const char* command, const char* message)
+{
+ struct map_session_data *pl_sd1 = NULL;
+ struct map_session_data *pl_sd2 = NULL;
+ struct map_session_data *pl_sd3 = NULL;
+ char player1[255], player2[255], player3[255];
+
+ nullpo_retr(-1, sd);
+
+ if (!message || !*message)
+ return -1;
+
+ if (sscanf(message, "%[^,],%[^,],%[^\r\n]", player1, player2, player3) != 3) {
+ clif_displaymessage(fd, "usage: @adopt <player1> <player2> <player3>.");
+ return -1;
+ }
+
+ printf("Adopting: --%s--%s--%s--\n",player1,player2,player3);
+
+ if((pl_sd1=map_nick2sd((char *) player1)) == NULL) {
+ sprintf(player2, "Cannot find player %s online", player1);
+ clif_displaymessage(fd, player2);
+ return -1;
+ }
+
+ if((pl_sd2=map_nick2sd((char *) player2)) == NULL) {
+ sprintf(player1, "Cannot find player %s online", player2);
+ clif_displaymessage(fd, player1);
+ return -1;
+ }
+
+ if((pl_sd3=map_nick2sd((char *) player3)) == NULL) {
+ sprintf(player1, "Cannot find player %s online", player3);
+ clif_displaymessage(fd, player1);
+ return -1;
+ }
+
+ if((pl_sd1->status.base_level < 70) || (pl_sd2->status.base_level < 70)){
+ clif_displaymessage(fd, "They are too young to be parents!");
+ return -1;
+ }
+
+ if (pc_adoption(pl_sd1, pl_sd2, pl_sd3) == 0) {
+ clif_displaymessage(fd, "They are family.. wish them luck");
+ return 0;
+ }
+ else
+ return -1;
+}
+
diff --git a/src/map/atcommand.h b/src/map/atcommand.h
index 3d84cd5b9..1160dccb7 100644
--- a/src/map/atcommand.h
+++ b/src/map/atcommand.h
@@ -112,20 +112,20 @@ enum AtCommandType {
AtCommand_CharSkReset,
AtCommand_CharStReset,
//by chbrules
- AtCommand_CharModel,
+ AtCommand_CharModel,
AtCommand_CharSKPoint,
- AtCommand_CharSTPoint,
- AtCommand_CharZeny,
+ AtCommand_CharSTPoint,
+// AtCommand_CharZeny, //now #zeny
AtCommand_RecallAll,
AtCommand_ReloadItemDB,
AtCommand_ReloadMobDB,
AtCommand_ReloadSkillDB,
-#ifndef TXT_ONLY
- AtCommand_Rehash,
-#else /* TXT_ONLY */
AtCommand_ReloadScript,
-#endif /* TXT_ONLY */
AtCommand_ReloadGMDB,
+ AtCommand_ReloadAtcommand,
+ AtCommand_ReloadBattleConf,
+ AtCommand_ReloadStatusDB,
+ AtCommand_ReloadPcDB,
AtCommand_MapInfo,
AtCommand_Dye,
AtCommand_Hstyle,
@@ -143,8 +143,9 @@ enum AtCommandType {
AtCommand_RepairAll, // [Valaris]
AtCommand_GuildRecall, // by Yor
AtCommand_PartyRecall, // by Yor
-// AtCommand_Nuke, // [Valaris]
+ AtCommand_Nuke, // [Valaris]
AtCommand_Enablenpc,
+ AtCommand_Hidenpc,
AtCommand_Disablenpc,
AtCommand_ServerTime, // by Yor
AtCommand_CharDelItem, // by Yor
@@ -157,8 +158,8 @@ enum AtCommandType {
AtCommand_EMail, // by Yor
AtCommand_Hatch,
AtCommand_Effect, // by Apple
- AtCommand_Char_Item_List, // by Yor
- AtCommand_Char_Storage_List, // by Yor
+// AtCommand_Char_Item_List, // by Yor, now #itemlist
+// AtCommand_Char_Storage_List, // by Yor, now #storagelist
AtCommand_Char_Cart_List, // by Yor
AtCommand_AddWarp, // by MouseJstr
AtCommand_Follow, // by MouseJstr
@@ -168,10 +169,7 @@ enum AtCommandType {
AtCommand_NpcMove, // by MouseJstr
AtCommand_Killable, // by MouseJstr
AtCommand_CharKillable, // by MouseJstr
- AtCommand_Chareffect, // by MouseJstr
- AtCommand_Chardye, // by MouseJstr
- AtCommand_Charhairstyle, // by MouseJstr
- AtCommand_Charhaircolor, // by MouseJstr
+// AtCommand_Chareffect, // by MouseJstr, now #effect
AtCommand_Dropall, // by MouseJstr
AtCommand_Chardropall, // by MouseJstr
AtCommand_Storeall, // by MouseJstr
@@ -190,6 +188,7 @@ enum AtCommandType {
AtCommand_Send,
AtCommand_SetBattleFlag,
AtCommand_UnMute,
+ AtCommand_Clearweather, // by Dexity
AtCommand_UpTime, // by MC Cameri
AtCommand_ChangeSex, // by MC Cameri
AtCommand_Mute, // [celest]
@@ -200,9 +199,14 @@ enum AtCommandType {
AtCommand_Identify, // by MC Cameri
AtCommand_Gmotd, // Added by MC Cameri, created by davidsiaw
AtCommand_MiscEffect, // by MC Cameri
+ AtCommand_MobSearch,
+ AtCommand_CleanMap,
+ AtCommand_NpcTalk,
+ AtCommand_PetTalk,
+ AtCommand_Users,
// SQL-only commands start
-#ifndef TXT_ONLY
+#ifndef TXT_ONLY
AtCommand_CheckMail, // [Valaris]
AtCommand_ListMail, // [Valaris]
AtCommand_ListNewMail, // [Valaris]
@@ -210,12 +214,40 @@ enum AtCommandType {
AtCommand_SendMail, // [Valaris]
AtCommand_DeleteMail, // [Valaris]
AtCommand_SendPriorityMail, // [Valaris]
- AtCommand_Sound, // [Valaris]
+// AtCommand_Sound, // [Valaris]
AtCommand_RefreshOnline, // [Valaris]
// SQL-only commands end
#endif
AtCommand_SkillTree, // by MouseJstr
-
+ AtCommand_Marry, // by MouseJstr
+ AtCommand_Divorce, // by MouseJstr
+ AtCommand_Rings, // by MouseJstr
+ AtCommand_Grind, // by MouseJstr
+ AtCommand_Grind2, // by MouseJstr
+
+ AtCommand_DMStart, // by MouseJstr
+ AtCommand_DMTick, // by MouseJstr
+
+ AtCommand_JumpToId, // by Dino9021
+ AtCommand_JumpToId2, // by Dino9021
+ AtCommand_RecallId, // by Dino9021
+ AtCommand_RecallId2, // by Dino9021
+ AtCommand_KickId, // by Dino9021
+ AtCommand_KickId2, // by Dino9021
+ AtCommand_ReviveId, // by Dino9021
+ AtCommand_ReviveId2, // by Dino9021
+ AtCommand_KillId, // by Dino9021
+ AtCommand_KillId2, // by Dino9021
+ AtCommand_CharKillableId, // by Dino9021
+ AtCommand_CharKillableId2, // by Dino9021
+ AtCommand_Sound,
+ AtCommand_UndisguiseAll,
+ AtCommand_DisguiseAll,
+ AtCommand_ChangeLook,
+ AtCommand_AutoLoot, //by Upa-Kun
+ AtCommand_MobInfo, //by Lupus
+ AtCommand_Adopt, // by Veider
+
// end
AtCommand_Unknown,
AtCommand_MAX
@@ -235,6 +267,7 @@ AtCommandType
is_atcommand(const int fd, struct map_session_data* sd, const char* message, int gmlvl);
AtCommandType atcommand(
+ struct map_session_data *sd,
const int level, const char* message, AtCommandInfo* info);
int get_atcommand_level(const AtCommandType type);
@@ -248,11 +281,12 @@ int atcommand_recall(const int fd, struct map_session_data* sd, const char* comm
int atcommand_config_read(const char *cfgName);
int msg_config_read(const char *cfgName);
+void do_final_msg();
char *estr_lower(char *str);
-char * job_name(int class);
-int e_mail_check(unsigned char *email);
+char * job_name(int class_);
+int e_mail_check(char *email);
#endif
diff --git a/src/map/battle.c b/src/map/battle.c
index 00ca5a9e0..077e5fc9b 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -12,6 +12,7 @@
#include "map.h"
#include "pc.h"
+#include "status.h"
#include "skill.h"
#include "mob.h"
#include "itemdb.h"
@@ -55,1259 +56,21 @@ int battle_counttargeted(struct block_list *bl,struct block_list *src,int target
return mob_counttargeted((struct mob_data *)bl,src,target_lv);
return 0;
}
-/*==========================================
- * ‘ÎÛ‚ÌClass‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_class(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return ((struct mob_data *)bl)->class;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->status.class;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- return ((struct pet_data *)bl)->class;
- else
- return 0;
-}
-/*==========================================
- * ‘ÎÛ‚Ì•ûŒü‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_dir(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return ((struct mob_data *)bl)->dir;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->dir;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- return ((struct pet_data *)bl)->dir;
- else
- return 0;
-}
-/*==========================================
- * ‘Îۂ̃Œƒxƒ‹‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_lv(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return ((struct mob_data *)bl)->level;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->status.base_level;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- return ((struct pet_data *)bl)->msd->pet.level;
- else
- return 0;
-}
-/*==========================================
- * ‘ÎÛ‚ÌŽË’ö‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_range(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return mob_db[((struct mob_data *)bl)->class].range;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->attackrange;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- return mob_db[((struct pet_data *)bl)->class].range;
- else
- return 0;
-}
-/*==========================================
- * ‘ÎÛ‚ÌHP‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_hp(struct block_list *bl)
-{
- nullpo_retr(1, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return ((struct mob_data *)bl)->hp;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->status.hp;
- else
- return 1;
-}
-/*==========================================
- * ‘ÎÛ‚ÌMHP‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_max_hp(struct block_list *bl)
-{
- nullpo_retr(1, bl);
- if(bl->type==BL_PC && ((struct map_session_data *)bl))
- return ((struct map_session_data *)bl)->status.max_hp;
- else {
- struct status_change *sc_data=battle_get_sc_data(bl);
- int max_hp=1;
- if(bl->type==BL_MOB && ((struct mob_data*)bl)) {
- max_hp = mob_db[((struct mob_data*)bl)->class].max_hp;
- if(battle_config.mobs_level_up) // mobs leveling up increase [Valaris]
- max_hp+=(((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class].lv)*battle_get_vit(bl);
- if(mob_db[((struct mob_data*)bl)->class].mexp > 0) {
- if(battle_config.mvp_hp_rate != 100)
- max_hp = (max_hp * battle_config.mvp_hp_rate)/100;
- }
- else {
- if(battle_config.monster_hp_rate != 100)
- max_hp = (max_hp * battle_config.monster_hp_rate)/100;
- }
- }
- else if(bl->type==BL_PET && ((struct pet_data*)bl)) {
- max_hp = mob_db[((struct pet_data*)bl)->class].max_hp;
- if(mob_db[((struct pet_data*)bl)->class].mexp > 0) {
- if(battle_config.mvp_hp_rate != 100)
- max_hp = (max_hp * battle_config.mvp_hp_rate)/100;
- }
- else {
- if(battle_config.monster_hp_rate != 100)
- max_hp = (max_hp * battle_config.monster_hp_rate)/100;
- }
- }
- if(sc_data) {
- if(sc_data[SC_APPLEIDUN].timer!=-1)
- max_hp += ((5+sc_data[SC_APPLEIDUN].val1*2+((sc_data[SC_APPLEIDUN].val2+1)>>1)
- +sc_data[SC_APPLEIDUN].val3/10) * max_hp)/100;
- }
- if(max_hp < 1) max_hp = 1;
- return max_hp;
- }
- return 1;
-}
-/*==========================================
- * ‘ÎÛ‚ÌStr‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_str(struct block_list *bl)
-{
- int str=0;
- struct status_change *sc_data;
-
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_MOB && ((struct mob_data *)bl)) {
- str = mob_db[((struct mob_data *)bl)->class].str;
- if(battle_config.mobs_level_up) // mobs leveling up increase [Valaris]
- str+=((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class].lv;
- }
- else if(bl->type==BL_PC && ((struct map_session_data *)bl))
- return ((struct map_session_data *)bl)->paramc[0];
- else if(bl->type==BL_PET && ((struct pet_data *)bl))
- str = mob_db[((struct pet_data *)bl)->class].str;
-
- if(sc_data) {
- if(sc_data[SC_LOUD].timer!=-1 && sc_data[SC_QUAGMIRE].timer == -1 && bl->type != BL_PC)
- str += 4;
- if( sc_data[SC_BLESSING].timer != -1 && bl->type != BL_PC){ // ƒuƒŒƒbƒVƒ“ƒO
- int race=battle_get_race(bl);
- if(battle_check_undead(race,battle_get_elem_type(bl)) || race==6 ) str >>= 1; // ˆ« –‚/•sŽ€
- else str += sc_data[SC_BLESSING].val1; // ‚»‚Ì‘¼
- }
- if(sc_data[SC_TRUESIGHT].timer!=-1 && bl->type != BL_PC) // ƒgƒDƒ‹[ƒTƒCƒg
- str += 5;
- }
- if(str < 0) str = 0;
- return str;
-}
-/*==========================================
- * ‘ÎÛ‚ÌAgi‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-
-int battle_get_agi(struct block_list *bl)
-{
- int agi=0;
- struct status_change *sc_data;
-
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl) {
- agi=mob_db[((struct mob_data *)bl)->class].agi;
- if(battle_config.mobs_level_up) // increase of mobs leveling up [Valaris]
- agi+=((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class].lv;
- }
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- agi=((struct map_session_data *)bl)->paramc[1];
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- agi=mob_db[((struct pet_data *)bl)->class].agi;
-
- if(sc_data) {
- if( sc_data[SC_INCREASEAGI].timer!=-1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1 &&
- bl->type != BL_PC) // ‘¬“x‘‰Á(PC‚Ípc.c‚Å)
- agi += 2+sc_data[SC_INCREASEAGI].val1;
-
- if(sc_data[SC_CONCENTRATE].timer!=-1 && sc_data[SC_QUAGMIRE].timer == -1 && bl->type != BL_PC)
- agi += agi*(2+sc_data[SC_CONCENTRATE].val1)/100;
-
- if(sc_data[SC_DECREASEAGI].timer!=-1) // ‘¬“xŒ¸­
- agi -= 2+sc_data[SC_DECREASEAGI].val1;
-
- if(sc_data[SC_QUAGMIRE].timer!=-1 ) { // ƒNƒ@ƒOƒ}ƒCƒA
- //agi >>= 1;
- int agib = agi*(sc_data[SC_QUAGMIRE].val1*10)/100;
- agi -= agib > 50 ? 50 : agib;
- }
- if(sc_data[SC_TRUESIGHT].timer!=-1 && bl->type != BL_PC) // ƒgƒDƒ‹[ƒTƒCƒg
- agi += 5;
- }
- if(agi < 0) agi = 0;
- return agi;
-}
-/*==========================================
- * ‘ÎÛ‚ÌVit‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_vit(struct block_list *bl)
-{
- int vit=0;
- struct status_change *sc_data;
-
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl) {
- vit=mob_db[((struct mob_data *)bl)->class].vit;
- if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
- vit+=((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class].lv;
- }
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- vit=((struct map_session_data *)bl)->paramc[2];
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- vit=mob_db[((struct pet_data *)bl)->class].vit;
- if(sc_data) {
- if(sc_data[SC_STRIPARMOR].timer != -1 && bl->type!=BL_PC)
- vit = vit*60/100;
- if(sc_data[SC_TRUESIGHT].timer!=-1 && bl->type != BL_PC) // ƒgƒDƒ‹[ƒTƒCƒg
- vit += 5;
- }
-
- if(vit < 0) vit = 0;
- return vit;
-}
-/*==========================================
- * ‘ÎÛ‚ÌInt‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_int(struct block_list *bl)
-{
- int int_=0;
- struct status_change *sc_data;
-
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl){
- int_=mob_db[((struct mob_data *)bl)->class].int_;
- if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
- int_+=((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class].lv;
- }
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- int_=((struct map_session_data *)bl)->paramc[3];
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- int_=mob_db[((struct pet_data *)bl)->class].int_;
-
- if(sc_data) {
- if( sc_data[SC_BLESSING].timer != -1 && bl->type != BL_PC){ // ƒuƒŒƒbƒVƒ“ƒO
- int race=battle_get_race(bl);
- if(battle_check_undead(race,battle_get_elem_type(bl)) || race==6 ) int_ >>= 1; // ˆ« –‚/•sŽ€
- else int_ += sc_data[SC_BLESSING].val1; // ‚»‚Ì‘¼
- }
- if( sc_data[SC_STRIPHELM].timer != -1 && bl->type != BL_PC)
- int_ = int_*60/100;
- if(sc_data[SC_TRUESIGHT].timer!=-1 && bl->type != BL_PC) // ƒgƒDƒ‹[ƒTƒCƒg
- int_ += 5;
- }
- if(int_ < 0) int_ = 0;
- return int_;
-}
-/*==========================================
- * ‘ÎÛ‚ÌDex‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_dex(struct block_list *bl)
-{
- int dex=0;
- struct status_change *sc_data;
-
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl) {
- dex=mob_db[((struct mob_data *)bl)->class].dex;
- if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
- dex+=((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class].lv;
- }
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- dex=((struct map_session_data *)bl)->paramc[4];
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- dex=mob_db[((struct pet_data *)bl)->class].dex;
-
- if(sc_data) {
- if(sc_data[SC_CONCENTRATE].timer!=-1 && sc_data[SC_QUAGMIRE].timer == -1 && bl->type != BL_PC)
- dex += dex*(2+sc_data[SC_CONCENTRATE].val1)/100;
-
- if( sc_data[SC_BLESSING].timer != -1 && bl->type != BL_PC){ // ƒuƒŒƒbƒVƒ“ƒO
- int race=battle_get_race(bl);
- if(battle_check_undead(race,battle_get_elem_type(bl)) || race==6 ) dex >>= 1; // ˆ« –‚/•sŽ€
- else dex += sc_data[SC_BLESSING].val1; // ‚»‚Ì‘¼
- }
-
- if(sc_data[SC_QUAGMIRE].timer!=-1 ) { // ƒNƒ@ƒOƒ}ƒCƒA
- // dex >>= 1;
- int dexb = dex*(sc_data[SC_QUAGMIRE].val1*10)/100;
- dex -= dexb > 50 ? 50 : dexb;
- }
- if(sc_data[SC_TRUESIGHT].timer!=-1 && bl->type != BL_PC) // ƒgƒDƒ‹[ƒTƒCƒg
- dex += 5;
- }
- if(dex < 0) dex = 0;
- return dex;
-}
-/*==========================================
- * ‘ÎÛ‚ÌLuk‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_luk(struct block_list *bl)
-{
- int luk=0;
- struct status_change *sc_data;
-
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl) {
- luk=mob_db[((struct mob_data *)bl)->class].luk;
- if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
- luk+=((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class].lv;
- }
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- luk=((struct map_session_data *)bl)->paramc[5];
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- luk=mob_db[((struct pet_data *)bl)->class].luk;
-
- if(sc_data) {
- if(sc_data[SC_GLORIA].timer!=-1 && bl->type != BL_PC) // ƒOƒƒŠƒA(PC‚Ípc.c‚Å)
- luk += 30;
- if(sc_data[SC_CURSE].timer!=-1 ) // Žô‚¢
- luk=0;
- if(sc_data[SC_TRUESIGHT].timer!=-1 && bl->type != BL_PC) // ƒgƒDƒ‹[ƒTƒCƒg
- luk += 5;
- }
- if(luk < 0) luk = 0;
- return luk;
-}
-
-/*==========================================
- * ‘ÎÛ‚ÌFlee‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å1ˆÈã
- *------------------------------------------
- */
-int battle_get_flee(struct block_list *bl)
-{
- int flee=1;
- struct status_change *sc_data;
-
- nullpo_retr(1, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- flee=((struct map_session_data *)bl)->flee;
- else
- flee=battle_get_agi(bl) + battle_get_lv(bl);
-
- if(sc_data) {
- if(sc_data[SC_WHISTLE].timer!=-1 && bl->type != BL_PC)
- flee += flee*(sc_data[SC_WHISTLE].val1+sc_data[SC_WHISTLE].val2
- +(sc_data[SC_WHISTLE].val3>>16))/100;
- if(sc_data[SC_BLIND].timer!=-1 && bl->type != BL_PC)
- flee -= flee*25/100;
- if(sc_data[SC_WINDWALK].timer!=-1 && bl->type != BL_PC) // ƒEƒBƒ“ƒhƒEƒH[ƒN
- flee += flee*(sc_data[SC_WINDWALK].val2)/100;
- if(sc_data[SC_SPIDERWEB].timer!=-1 && bl->type != BL_PC) //ƒXƒpƒCƒ_[ƒEƒFƒu
- flee -= flee*50/100;
- }
- if(flee < 1) flee = 1;
- return flee;
-}
-/*==========================================
- * ‘ÎÛ‚ÌHit‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å1ˆÈã
- *------------------------------------------
- */
-int battle_get_hit(struct block_list *bl)
-{
- int hit=1;
- struct status_change *sc_data;
-
- nullpo_retr(1, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- hit=((struct map_session_data *)bl)->hit;
- else
- hit=battle_get_dex(bl) + battle_get_lv(bl);
-
- if(sc_data) {
- if(sc_data[SC_HUMMING].timer!=-1 && bl->type != BL_PC) //
- hit += hit*(sc_data[SC_HUMMING].val1*2+sc_data[SC_HUMMING].val2
- +sc_data[SC_HUMMING].val3)/100;
- if(sc_data[SC_BLIND].timer!=-1 && bl->type != BL_PC) // Žô‚¢
- hit -= hit*25/100;
- if(sc_data[SC_TRUESIGHT].timer!=-1 && bl->type != BL_PC) // ƒgƒDƒ‹[ƒTƒCƒg
- hit += 3*(sc_data[SC_TRUESIGHT].val1);
- if(sc_data[SC_CONCENTRATION].timer!=-1 && bl->type != BL_PC) //ƒRƒ“ƒZƒ“ƒgƒŒ[ƒVƒ‡ƒ“
- hit += (hit*(10*(sc_data[SC_CONCENTRATION].val1)))/100;
- }
- if(hit < 1) hit = 1;
- return hit;
-}
-/*==========================================
- * ‘ÎÛ‚ÌŠ®‘S‰ñ”ð‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å1ˆÈã
- *------------------------------------------
- */
-int battle_get_flee2(struct block_list *bl)
-{
- int flee2=1;
- struct status_change *sc_data;
-
- nullpo_retr(1, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl){
- flee2 = battle_get_luk(bl) + 10;
- flee2 += ((struct map_session_data *)bl)->flee2 - (((struct map_session_data *)bl)->paramc[5] + 10);
- }
- else
- flee2=battle_get_luk(bl)+1;
-
- if(sc_data) {
- if(sc_data[SC_WHISTLE].timer!=-1 && bl->type != BL_PC)
- flee2 += (sc_data[SC_WHISTLE].val1+sc_data[SC_WHISTLE].val2
- +(sc_data[SC_WHISTLE].val3&0xffff))*10;
- }
- if(flee2 < 1) flee2 = 1;
- return flee2;
-}
-/*==========================================
- * ‘Îۂ̃NƒŠƒeƒBƒJƒ‹‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å1ˆÈã
- *------------------------------------------
- */
-int battle_get_critical(struct block_list *bl)
-{
- int critical=1;
- struct status_change *sc_data;
-
- nullpo_retr(1, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl){
- critical = battle_get_luk(bl)*3 + 10;
- critical += ((struct map_session_data *)bl)->critical - ((((struct map_session_data *)bl)->paramc[5]*3) + 10);
- }
- else
- critical=battle_get_luk(bl)*3 + 1;
-
- if(sc_data) {
- if(sc_data[SC_FORTUNE].timer!=-1 && bl->type != BL_PC)
- critical += (10+sc_data[SC_FORTUNE].val1+sc_data[SC_FORTUNE].val2
- +sc_data[SC_FORTUNE].val3)*10;
- if(sc_data[SC_EXPLOSIONSPIRITS].timer!=-1 && bl->type != BL_PC)
- critical += sc_data[SC_EXPLOSIONSPIRITS].val2;
- if(sc_data[SC_TRUESIGHT].timer!=-1 && bl->type != BL_PC) //ƒgƒDƒ‹[ƒTƒCƒg
- critical += critical*sc_data[SC_TRUESIGHT].val1/100;
- }
- if(critical < 1) critical = 1;
- return critical;
-}
-/*==========================================
- * base_atk‚̎擾
- * –ß‚è‚Í®”‚Å1ˆÈã
- *------------------------------------------
- */
-int battle_get_baseatk(struct block_list *bl)
-{
- struct status_change *sc_data;
- int batk=1;
-
- nullpo_retr(1, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- batk = ((struct map_session_data *)bl)->base_atk; //ݒ肳‚ê‚Ä‚¢‚ébase_atk
- else { //‚»‚êˆÈŠO‚È‚ç
- int str,dstr;
- str = battle_get_str(bl); //STR
- dstr = str/10;
- batk = dstr*dstr + str; //base_atk‚ðŒvŽZ‚·‚é
- }
- if(sc_data) { //ó‘ÔˆÙí‚ ‚è
- if(sc_data[SC_PROVOKE].timer!=-1 && bl->type != BL_PC) //PC‚Ńvƒƒ{ƒbƒN(SM_PROVOKE)ó‘Ô
- batk = batk*(100+2*sc_data[SC_PROVOKE].val1)/100; //base_atk‘‰Á
- if(sc_data[SC_CURSE].timer!=-1 ) //Žô‚í‚ê‚Ä‚¢‚½‚ç
- batk -= batk*25/100; //base_atk‚ª25%Œ¸­
- if(sc_data[SC_CONCENTRATION].timer!=-1 && bl->type != BL_PC) //ƒRƒ“ƒZƒ“ƒgƒŒ[ƒVƒ‡ƒ“
- batk += batk*(5*sc_data[SC_CONCENTRATION].val1)/100;
- if(sc_data[SC_EDP].timer != -1) // [Celest]
- batk += batk*(50+50*sc_data[SC_EDP].val1)/100;
- }
- if(batk < 1) batk = 1; //base_atk‚ÍÅ’á‚Å‚à1
- return batk;
-}
-/*==========================================
- * ‘ÎÛ‚ÌAtk‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_atk(struct block_list *bl)
-{
- struct status_change *sc_data;
- int atk=0;
-
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- atk = ((struct map_session_data*)bl)->watk;
- else if(bl->type==BL_MOB && (struct mob_data *)bl)
- atk = mob_db[((struct mob_data*)bl)->class].atk1;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- atk = mob_db[((struct pet_data*)bl)->class].atk1;
-
- if(sc_data) {
- if(sc_data[SC_PROVOKE].timer!=-1 && bl->type != BL_PC)
- atk = atk*(100+2*sc_data[SC_PROVOKE].val1)/100;
- if(sc_data[SC_CURSE].timer!=-1 )
- atk -= atk*25/100;
- if(sc_data[SC_CONCENTRATION].timer!=-1 && bl->type != BL_PC) //ƒRƒ“ƒZƒ“ƒgƒŒ[ƒVƒ‡ƒ“
- atk += atk*(5*sc_data[SC_CONCENTRATION].val1)/100;
- }
- if(atk < 0) atk = 0;
- return atk;
-}
-/*==========================================
- * ‘Îۂ̶ŽèAtk‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_atk_(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl){
- int atk=((struct map_session_data*)bl)->watk_;
-
- if(((struct map_session_data *)bl)->sc_data[SC_CURSE].timer!=-1 )
- atk -= atk*25/100;
- return atk;
- }
- else
- return 0;
-}
-/*==========================================
- * ‘ÎÛ‚ÌAtk2‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_atk2(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data*)bl)->watk2;
- else {
- struct status_change *sc_data=battle_get_sc_data(bl);
- int atk2=0;
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- atk2 = mob_db[((struct mob_data*)bl)->class].atk2;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- atk2 = mob_db[((struct pet_data*)bl)->class].atk2;
- if(sc_data) {
- if( sc_data[SC_IMPOSITIO].timer!=-1)
- atk2 += sc_data[SC_IMPOSITIO].val1*5;
- if( sc_data[SC_PROVOKE].timer!=-1 )
- atk2 = atk2*(100+2*sc_data[SC_PROVOKE].val1)/100;
- if( sc_data[SC_CURSE].timer!=-1 )
- atk2 -= atk2*25/100;
- if(sc_data[SC_DRUMBATTLE].timer!=-1)
- atk2 += sc_data[SC_DRUMBATTLE].val2;
- if(sc_data[SC_NIBELUNGEN].timer!=-1 && (battle_get_element(bl)/10) >= 8 )
- atk2 += sc_data[SC_NIBELUNGEN].val2;
- if(sc_data[SC_STRIPWEAPON].timer!=-1)
- atk2 = atk2*90/100;
- if(sc_data[SC_CONCENTRATION].timer!=-1) //ƒRƒ“ƒZƒ“ƒgƒŒ[ƒVƒ‡ƒ“
- atk2 += atk2*(5*sc_data[SC_CONCENTRATION].val1)/100;
- }
- if(atk2 < 0) atk2 = 0;
- return atk2;
- }
- return 0;
-}
-/*==========================================
- * ‘Îۂ̶ŽèAtk2‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_atk_2(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data*)bl)->watk_2;
- else
- return 0;
-}
-/*==========================================
- * ‘ÎÛ‚ÌMAtk1‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_matk1(struct block_list *bl)
-{
- struct status_change *sc_data;
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_MOB){
- int matk,int_=battle_get_int(bl);
- matk = int_+(int_/5)*(int_/5);
-
- if(sc_data)
- if(sc_data[SC_MINDBREAKER].timer!=-1 && bl->type != BL_PC)
- matk = matk*(100+2*sc_data[SC_MINDBREAKER].val1)/100;
- return matk;
- }
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->matk1;
- else if(bl->type==BL_PET){
- int matk,int_=battle_get_int(bl);
- matk = int_+(int_/5)*(int_/5);
-
- if(sc_data)
- if(sc_data[SC_MINDBREAKER].timer!=-1 && bl->type != BL_PC)
- matk = matk*(100+2*sc_data[SC_MINDBREAKER].val1)/100;
- return matk;
- }
- else
- return 0;
-}
-/*==========================================
- * ‘ÎÛ‚ÌMAtk2‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_matk2(struct block_list *bl)
-{
- struct status_change *sc_data=battle_get_sc_data(bl);
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB){
- int matk,int_=battle_get_int(bl);
- matk = int_+(int_/7)*(int_/7);
-
- if(sc_data)
- if(sc_data[SC_MINDBREAKER].timer!=-1 && bl->type != BL_PC)
- matk = matk*(100+2*sc_data[SC_MINDBREAKER].val1)/100;
- return matk;
- }
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->matk2;
- else if(bl->type==BL_PET){
- int matk,int_=battle_get_int(bl);
- matk = int_+(int_/7)*(int_/7);
- if(sc_data)
- if(sc_data[SC_MINDBREAKER].timer!=-1 && bl->type != BL_PC)
- matk = matk*(100+2*sc_data[SC_MINDBREAKER].val1)/100;
- return matk;
- }
- else
- return 0;
-}
-/*==========================================
- * ‘ÎÛ‚ÌDef‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_def(struct block_list *bl)
-{
- struct status_change *sc_data;
- int def=0,skilltimer=-1,skillid=0;
-
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl){
- def = ((struct map_session_data *)bl)->def;
- skilltimer = ((struct map_session_data *)bl)->skilltimer;
- skillid = ((struct map_session_data *)bl)->skillid;
- }
- else if(bl->type==BL_MOB && (struct mob_data *)bl) {
- def = mob_db[((struct mob_data *)bl)->class].def;
- skilltimer = ((struct mob_data *)bl)->skilltimer;
- skillid = ((struct mob_data *)bl)->skillid;
- }
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- def = mob_db[((struct pet_data *)bl)->class].def;
-
- if(def < 1000000) {
- if(sc_data) {
- //ƒL[ƒsƒ“ƒOŽž‚ÍDEF100
- if( sc_data[SC_KEEPING].timer!=-1)
- def = 100;
- //ƒvƒƒ{ƒbƒNŽž‚ÍŒ¸ŽZ
- if( sc_data[SC_PROVOKE].timer!=-1 && bl->type != BL_PC)
- def = (def*(100 - 6*sc_data[SC_PROVOKE].val1)+50)/100;
- //푾ŒÛ‚Ì‹¿‚«Žž‚͉ÁŽZ
- if( sc_data[SC_DRUMBATTLE].timer!=-1 && bl->type != BL_PC)
- def += sc_data[SC_DRUMBATTLE].val3;
- //“łɂ©‚©‚Á‚Ä‚¢‚鎞‚ÍŒ¸ŽZ
- if(sc_data[SC_POISON].timer!=-1 && bl->type != BL_PC)
- def = def*75/100;
- //ƒXƒgƒŠƒbƒvƒV[ƒ‹ƒhŽž‚ÍŒ¸ŽZ
- if(sc_data[SC_STRIPSHIELD].timer!=-1 && bl->type != BL_PC)
- def = def*85/100;
- //ƒVƒOƒiƒ€ƒNƒ‹ƒVƒXŽž‚ÍŒ¸ŽZ
- if(sc_data[SC_SIGNUMCRUCIS].timer!=-1 && bl->type != BL_PC)
- def = def * (100 - sc_data[SC_SIGNUMCRUCIS].val2)/100;
- //‰i‰“‚̬“׎ž‚ÍDEF0‚ɂȂé
- if(sc_data[SC_ETERNALCHAOS].timer!=-1 && bl->type != BL_PC)
- def = 0;
- //“€Œ‹AΉ»Žž‚͉EƒVƒtƒg
- if(sc_data[SC_FREEZE].timer != -1 || (sc_data[SC_STONE].timer != -1 && sc_data[SC_STONE].val2 == 0))
- def >>= 1;
- //ƒRƒ“ƒZƒ“ƒgƒŒ[ƒVƒ‡ƒ“Žž‚ÍŒ¸ŽZ
- if( sc_data[SC_CONCENTRATION].timer!=-1 && bl->type != BL_PC)
- def = (def*(100 - 5*sc_data[SC_CONCENTRATION].val1))/100;
- }
- //‰r¥’†‚͉r¥ŽžŒ¸ŽZ—¦‚ÉŠî‚¢‚ÄŒ¸ŽZ
- if(skilltimer != -1) {
- int def_rate = skill_get_castdef(skillid);
- if(def_rate != 0)
- def = (def * (100 - def_rate))/100;
- }
- }
- if(def < 0) def = 0;
- return def;
-}
-/*==========================================
- * ‘ÎÛ‚ÌMDef‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_mdef(struct block_list *bl)
-{
- struct status_change *sc_data;
- int mdef=0;
-
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- mdef = ((struct map_session_data *)bl)->mdef;
- else if(bl->type==BL_MOB && (struct mob_data *)bl)
- mdef = mob_db[((struct mob_data *)bl)->class].mdef;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- mdef = mob_db[((struct pet_data *)bl)->class].mdef;
-
- if(mdef < 1000000) {
- if(sc_data) {
- //ƒoƒŠƒA[ó‘ÔŽž‚ÍMDEF100
- if(sc_data[SC_BARRIER].timer != -1)
- mdef = 100;
- //“€Œ‹AΉ»Žž‚Í1.25”{
- if(sc_data[SC_FREEZE].timer != -1 || (sc_data[SC_STONE].timer != -1 && sc_data[SC_STONE].val2 == 0))
- mdef = mdef*125/100;
- if( sc_data[SC_MINDBREAKER].timer!=-1 && bl->type != BL_PC)
- mdef -= (mdef*6*sc_data[SC_MINDBREAKER].val1)/100;
- }
- }
- if(mdef < 0) mdef = 0;
- return mdef;
-}
-/*==========================================
- * ‘ÎÛ‚ÌDef2‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å1ˆÈã
- *------------------------------------------
- */
-int battle_get_def2(struct block_list *bl)
-{
- struct status_change *sc_data;
- int def2=1;
-
- nullpo_retr(1, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_PC)
- def2 = ((struct map_session_data *)bl)->def2;
- else if(bl->type==BL_MOB)
- def2 = mob_db[((struct mob_data *)bl)->class].vit;
- else if(bl->type==BL_PET)
- def2 = mob_db[((struct pet_data *)bl)->class].vit;
-
- if(sc_data) {
- if( sc_data[SC_ANGELUS].timer!=-1 && bl->type != BL_PC)
- def2 = def2*(110+5*sc_data[SC_ANGELUS].val1)/100;
- if( sc_data[SC_PROVOKE].timer!=-1 && bl->type != BL_PC)
- def2 = (def2*(100 - 6*sc_data[SC_PROVOKE].val1)+50)/100;
- if(sc_data[SC_POISON].timer!=-1 && bl->type != BL_PC)
- def2 = def2*75/100;
- //ƒRƒ“ƒZƒ“ƒgƒŒ[ƒVƒ‡ƒ“Žž‚ÍŒ¸ŽZ
- if( sc_data[SC_CONCENTRATION].timer!=-1 && bl->type != BL_PC)
- def2 = def2*(100 - 5*sc_data[SC_CONCENTRATION].val1)/100;
- }
- if(def2 < 1) def2 = 1;
- return def2;
-}
-/*==========================================
- * ‘ÎÛ‚ÌMDef2‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å0ˆÈã
- *------------------------------------------
- */
-int battle_get_mdef2(struct block_list *bl)
-{
- int mdef2=0;
- struct status_change *sc_data=battle_get_sc_data(bl);
-
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB)
- mdef2 = mob_db[((struct mob_data *)bl)->class].int_ + (mob_db[((struct mob_data *)bl)->class].vit>>1);
- else if(bl->type==BL_PC)
- mdef2 = ((struct map_session_data *)bl)->mdef2 + (((struct map_session_data *)bl)->paramc[2]>>1);
- else if(bl->type==BL_PET)
- mdef2 = mob_db[((struct pet_data *)bl)->class].int_ + (mob_db[((struct pet_data *)bl)->class].vit>>1);
- if(sc_data) {
- if( sc_data[SC_MINDBREAKER].timer!=-1 && bl->type != BL_PC)
- mdef2 -= (mdef2*6*sc_data[SC_MINDBREAKER].val1)/100;
- }
- if(mdef2 < 0) mdef2 = 0;
- return mdef2;
-}
-/*==========================================
- * ‘ÎÛ‚ÌSpeed(ˆÚ“®‘¬“x)‚ð•Ô‚·(”Ä—p)
- * –ß‚è‚Í®”‚Å1ˆÈã
- * Speed‚ͬ‚³‚¢‚Ù‚¤‚ªˆÚ“®‘¬“x‚ª‘¬‚¢
- *------------------------------------------
- */
-int battle_get_speed(struct block_list *bl)
-{
- nullpo_retr(1000, bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->speed;
- else {
- struct status_change *sc_data=battle_get_sc_data(bl);
- int speed = 1000;
- if(bl->type==BL_MOB && (struct mob_data *)bl) {
- speed = ((struct mob_data *)bl)->speed;
- if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
- speed-=((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class].lv;
- }
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- speed = ((struct pet_data *)bl)->msd->petDB->speed;
-
- if(sc_data) {
- //‘¬“x‘‰ÁŽž‚Í25%Œ¸ŽZ
- if(sc_data[SC_INCREASEAGI].timer!=-1 && sc_data[SC_DONTFORGETME].timer == -1)
- speed -= speed*25/100;
- //‘¬“xŒ¸­Žž‚Í25%‰ÁŽZ
- if(sc_data[SC_DECREASEAGI].timer!=-1)
- speed = speed*125/100;
- //ƒNƒ@ƒOƒ}ƒCƒAŽž‚Í50%‰ÁŽZ
- if(sc_data[SC_QUAGMIRE].timer!=-1)
- speed = speed*3/2;
- //Ž„‚ð–Y‚ê‚È‚¢‚ÅcŽž‚͉ÁŽZ
- if(sc_data[SC_DONTFORGETME].timer!=-1)
- speed = speed*(100+sc_data[SC_DONTFORGETME].val1*2 + sc_data[SC_DONTFORGETME].val2 + (sc_data[SC_DONTFORGETME].val3&0xffff))/100;
- //‹à„Žž‚Í25%‰ÁŽZ
- if(sc_data[SC_STEELBODY].timer!=-1)
- speed = speed*125/100;
- //ƒfƒBƒtƒFƒ“ƒ_[Žž‚͉ÁŽZ
- if(sc_data[SC_DEFENDER].timer!=-1)
- speed = (speed * (155 - sc_data[SC_DEFENDER].val1*5)) / 100;
- //—x‚èó‘Ô‚Í4”{’x‚¢
- if(sc_data[SC_DANCING].timer!=-1 )
- speed*=4;
- //Žô‚¢Žž‚Í450‰ÁŽZ
- if(sc_data[SC_CURSE].timer!=-1)
- speed = speed + 450;
- //ƒEƒBƒ“ƒhƒEƒH[ƒNŽž‚ÍLv*2%Œ¸ŽZ
- if(sc_data[SC_WINDWALK].timer!=-1)
- speed -= (speed*(sc_data[SC_WINDWALK].val1*2))/100;
- if(sc_data[SC_SLOWDOWN].timer!=-1)
- speed = speed*150/100;
- }
- if(speed < 1) speed = 1;
- return speed;
- }
-
- return 1000;
-}
-/*==========================================
- * ‘ÎÛ‚ÌaDelay(UŒ‚ŽžƒfƒBƒŒƒC)‚ð•Ô‚·(”Ä—p)
- * aDelay‚ͬ‚³‚¢‚Ù‚¤‚ªUŒ‚‘¬“x‚ª‘¬‚¢
- *------------------------------------------
- */
-int battle_get_adelay(struct block_list *bl)
-{
- nullpo_retr(4000, bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- return (((struct map_session_data *)bl)->aspd<<1);
- else {
- struct status_change *sc_data=battle_get_sc_data(bl);
- int adelay=4000,aspd_rate = 100,i;
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- adelay = mob_db[((struct mob_data *)bl)->class].adelay;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- adelay = mob_db[((struct pet_data *)bl)->class].adelay;
-
- if(sc_data) {
- //ƒc[ƒnƒ“ƒhƒNƒCƒbƒPƒ“Žg—pŽž‚ŃNƒ@ƒOƒ}ƒCƒA‚Å‚àŽ„‚ð–Y‚ê‚È‚¢‚Åc‚Å‚à‚È‚¢Žž‚Í3Š„Œ¸ŽZ
- if(sc_data[SC_TWOHANDQUICKEN].timer != -1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) // 2HQ
- aspd_rate -= 30;
- //ƒAƒhƒŒƒiƒŠƒ“ƒ‰ƒbƒVƒ…Žg—pŽž‚Ńc[ƒnƒ“ƒhƒNƒCƒbƒPƒ“‚Å‚àƒNƒ@ƒOƒ}ƒCƒA‚Å‚àŽ„‚ð–Y‚ê‚È‚¢‚Åc‚Å‚à‚È‚¢Žž‚Í
- if(sc_data[SC_ADRENALINE].timer != -1 && sc_data[SC_TWOHANDQUICKEN].timer == -1 &&
- sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) { // ƒAƒhƒŒƒiƒŠƒ“ƒ‰ƒbƒVƒ…
- //Žg—pŽÒ‚ƃp[ƒeƒBƒƒ“ƒo[‚ÅŠi·‚ªo‚éÝ’è‚łȂ¯‚ê‚Î3Š„Œ¸ŽZ
- if(sc_data[SC_ADRENALINE].val2 || !battle_config.party_skill_penaly)
- aspd_rate -= 30;
- //‚»‚¤‚łȂ¯‚ê‚Î2.5Š„Œ¸ŽZ
- else
- aspd_rate -= 25;
- }
- //ƒXƒsƒAƒNƒBƒbƒPƒ“Žž‚ÍŒ¸ŽZ
- if(sc_data[SC_SPEARSQUICKEN].timer != -1 && sc_data[SC_ADRENALINE].timer == -1 &&
- sc_data[SC_TWOHANDQUICKEN].timer == -1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) // ƒXƒsƒAƒNƒBƒbƒPƒ“
- aspd_rate -= sc_data[SC_SPEARSQUICKEN].val2;
- //—[“ú‚̃AƒTƒVƒ“ƒNƒƒXŽž‚ÍŒ¸ŽZ
- if(sc_data[SC_ASSNCROS].timer!=-1 && // —[—z‚̃AƒTƒVƒ“ƒNƒƒX
- sc_data[SC_TWOHANDQUICKEN].timer==-1 && sc_data[SC_ADRENALINE].timer==-1 && sc_data[SC_SPEARSQUICKEN].timer==-1 &&
- sc_data[SC_DONTFORGETME].timer == -1)
- aspd_rate -= 5+sc_data[SC_ASSNCROS].val1+sc_data[SC_ASSNCROS].val2+sc_data[SC_ASSNCROS].val3;
- //Ž„‚ð–Y‚ê‚È‚¢‚ÅcŽž‚͉ÁŽZ
- if(sc_data[SC_DONTFORGETME].timer!=-1) // Ž„‚ð–Y‚ê‚È‚¢‚Å
- aspd_rate += sc_data[SC_DONTFORGETME].val1*3 + sc_data[SC_DONTFORGETME].val2 + (sc_data[SC_DONTFORGETME].val3>>16);
- //‹à„Žž25%‰ÁŽZ
- if(sc_data[SC_STEELBODY].timer!=-1) // ‹à„
- aspd_rate += 25;
- //‘‘¬ƒ|[ƒVƒ‡ƒ“Žg—pŽž‚ÍŒ¸ŽZ
- if( sc_data[i=SC_SPEEDPOTION2].timer!=-1 || sc_data[i=SC_SPEEDPOTION1].timer!=-1 || sc_data[i=SC_SPEEDPOTION0].timer!=-1)
- aspd_rate -= sc_data[i].val2;
- //ƒfƒBƒtƒFƒ“ƒ_[Žž‚͉ÁŽZ
- if(sc_data[SC_DEFENDER].timer != -1)
- adelay += (1100 - sc_data[SC_DEFENDER].val1*100);
- }
- if(aspd_rate != 100)
- adelay = adelay*aspd_rate/100;
- if(adelay < battle_config.monster_max_aspd<<1) adelay = battle_config.monster_max_aspd<<1;
- return adelay;
- }
- return 4000;
-}
-int battle_get_amotion(struct block_list *bl)
-{
- nullpo_retr(2000, bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->amotion;
- else {
- struct status_change *sc_data=battle_get_sc_data(bl);
- int amotion=2000,aspd_rate = 100,i;
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- amotion = mob_db[((struct mob_data *)bl)->class].amotion;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- amotion = mob_db[((struct pet_data *)bl)->class].amotion;
-
- if(sc_data) {
- if(sc_data[SC_TWOHANDQUICKEN].timer != -1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) // 2HQ
- aspd_rate -= 30;
- if(sc_data[SC_ADRENALINE].timer != -1 && sc_data[SC_TWOHANDQUICKEN].timer == -1 &&
- sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) { // ƒAƒhƒŒƒiƒŠƒ“ƒ‰ƒbƒVƒ…
- if(sc_data[SC_ADRENALINE].val2 || !battle_config.party_skill_penaly)
- aspd_rate -= 30;
- else
- aspd_rate -= 25;
- }
- if(sc_data[SC_SPEARSQUICKEN].timer != -1 && sc_data[SC_ADRENALINE].timer == -1 &&
- sc_data[SC_TWOHANDQUICKEN].timer == -1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) // ƒXƒsƒAƒNƒBƒbƒPƒ“
- aspd_rate -= sc_data[SC_SPEARSQUICKEN].val2;
- if(sc_data[SC_ASSNCROS].timer!=-1 && // —[—z‚̃AƒTƒVƒ“ƒNƒƒX
- sc_data[SC_TWOHANDQUICKEN].timer==-1 && sc_data[SC_ADRENALINE].timer==-1 && sc_data[SC_SPEARSQUICKEN].timer==-1 &&
- sc_data[SC_DONTFORGETME].timer == -1)
- aspd_rate -= 5+sc_data[SC_ASSNCROS].val1+sc_data[SC_ASSNCROS].val2+sc_data[SC_ASSNCROS].val3;
- if(sc_data[SC_DONTFORGETME].timer!=-1) // Ž„‚ð–Y‚ê‚È‚¢‚Å
- aspd_rate += sc_data[SC_DONTFORGETME].val1*3 + sc_data[SC_DONTFORGETME].val2 + (sc_data[SC_DONTFORGETME].val3>>16);
- if(sc_data[SC_STEELBODY].timer!=-1) // ‹à„
- aspd_rate += 25;
- if( sc_data[i=SC_SPEEDPOTION2].timer!=-1 || sc_data[i=SC_SPEEDPOTION1].timer!=-1 || sc_data[i=SC_SPEEDPOTION0].timer!=-1)
- aspd_rate -= sc_data[i].val2;
- if(sc_data[SC_DEFENDER].timer != -1)
- amotion += (550 - sc_data[SC_DEFENDER].val1*50);
- }
- if(aspd_rate != 100)
- amotion = amotion*aspd_rate/100;
- if(amotion < battle_config.monster_max_aspd) amotion = battle_config.monster_max_aspd;
- return amotion;
- }
- return 2000;
-}
-int battle_get_dmotion(struct block_list *bl)
-{
- int ret;
- struct status_change *sc_data;
-
- nullpo_retr(0, bl);
- sc_data = battle_get_sc_data(bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl){
- ret=mob_db[((struct mob_data *)bl)->class].dmotion;
- if(battle_config.monster_damage_delay_rate != 100)
- ret = ret*battle_config.monster_damage_delay_rate/400;
- }
- else if(bl->type==BL_PC && (struct map_session_data *)bl){
- ret=((struct map_session_data *)bl)->dmotion;
- if(battle_config.pc_damage_delay_rate != 100)
- ret = ret*battle_config.pc_damage_delay_rate/400;
- }
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- ret=mob_db[((struct pet_data *)bl)->class].dmotion;
- else
- return 2000;
-
- if((sc_data && (sc_data[SC_ENDURE].timer!=-1 || sc_data[SC_BERSERK].timer!=-1)) ||
- (bl->type == BL_PC && ((struct map_session_data *)bl)->special_state.infinite_endure))
- ret=0;
-
- return ret;
-}
-int battle_get_element(struct block_list *bl)
-{
- int ret = 20;
- struct status_change *sc_data;
-
- nullpo_retr(ret, bl);
- sc_data = battle_get_sc_data(bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl) // 10‚̈ÊLv*2A‚P‚̈ʑ®«
- ret=((struct mob_data *)bl)->def_ele;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- ret=20+((struct map_session_data *)bl)->def_ele; // –hŒä‘®«Lv1
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- ret = mob_db[((struct pet_data *)bl)->class].element;
-
- if(sc_data) {
- if( sc_data[SC_BENEDICTIO].timer!=-1 ) // ¹‘Ì~•Ÿ
- ret=26;
- if( sc_data[SC_FREEZE].timer!=-1 ) // “€Œ‹
- ret=21;
- if( sc_data[SC_STONE].timer!=-1 && sc_data[SC_STONE].val2==0)
- ret=22;
- }
-
- return ret;
-}
-int battle_get_attack_element(struct block_list *bl)
-{
- int ret = 0;
- struct status_change *sc_data=battle_get_sc_data(bl);
-
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- ret=0;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- ret=((struct map_session_data *)bl)->atk_ele;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- ret=0;
-
- if(sc_data) {
- if( sc_data[SC_FROSTWEAPON].timer!=-1) // ƒtƒƒXƒgƒEƒFƒ|ƒ“
- ret=1;
- if( sc_data[SC_SEISMICWEAPON].timer!=-1) // ƒTƒCƒYƒ~ƒbƒNƒEƒFƒ|ƒ“
- ret=2;
- if( sc_data[SC_FLAMELAUNCHER].timer!=-1) // ƒtƒŒ[ƒ€ƒ‰ƒ“ƒ`ƒƒ[
- ret=3;
- if( sc_data[SC_LIGHTNINGLOADER].timer!=-1) // ƒ‰ƒCƒgƒjƒ“ƒOƒ[ƒ_[
- ret=4;
- if( sc_data[SC_ENCPOISON].timer!=-1) // ƒGƒ“ƒ`ƒƒƒ“ƒgƒ|ƒCƒYƒ“
- ret=5;
- if( sc_data[SC_ASPERSIO].timer!=-1) // ƒAƒXƒyƒ‹ƒVƒI
- ret=6;
- }
-
- return ret;
-}
-int battle_get_attack_element2(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl) {
- int ret = ((struct map_session_data *)bl)->atk_ele_;
- struct status_change *sc_data = ((struct map_session_data *)bl)->sc_data;
-
- if(sc_data) {
- if( sc_data[SC_FROSTWEAPON].timer!=-1) // ƒtƒƒXƒgƒEƒFƒ|ƒ“
- ret=1;
- if( sc_data[SC_SEISMICWEAPON].timer!=-1) // ƒTƒCƒYƒ~ƒbƒNƒEƒFƒ|ƒ“
- ret=2;
- if( sc_data[SC_FLAMELAUNCHER].timer!=-1) // ƒtƒŒ[ƒ€ƒ‰ƒ“ƒ`ƒƒ[
- ret=3;
- if( sc_data[SC_LIGHTNINGLOADER].timer!=-1) // ƒ‰ƒCƒgƒjƒ“ƒOƒ[ƒ_[
- ret=4;
- if( sc_data[SC_ENCPOISON].timer!=-1) // ƒGƒ“ƒ`ƒƒƒ“ƒgƒ|ƒCƒYƒ“
- ret=5;
- if( sc_data[SC_ASPERSIO].timer!=-1) // ƒAƒXƒyƒ‹ƒVƒI
- ret=6;
- }
- return ret;
- }
- return 0;
-}
-int battle_get_party_id(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->status.party_id;
- else if(bl->type==BL_MOB && (struct mob_data *)bl){
- struct mob_data *md=(struct mob_data *)bl;
- if( md->master_id>0 )
- return -md->master_id;
- return -md->bl.id;
- }
- else if(bl->type==BL_SKILL && (struct skill_unit *)bl)
- return ((struct skill_unit *)bl)->group->party_id;
- else
- return 0;
-}
-int battle_get_guild_id(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->status.guild_id;
- else if(bl->type==BL_MOB && (struct mob_data *)bl)
- return ((struct mob_data *)bl)->class;
- else if(bl->type==BL_SKILL && (struct skill_unit *)bl)
- return ((struct skill_unit *)bl)->group->guild_id;
- else
- return 0;
-}
-int battle_get_race(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return mob_db[((struct mob_data *)bl)->class].race;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return 7;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- return mob_db[((struct pet_data *)bl)->class].race;
- else
- return 0;
-}
-int battle_get_size(struct block_list *bl)
-{
- nullpo_retr(1, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return mob_db[((struct mob_data *)bl)->class].size;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return 1;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- return mob_db[((struct pet_data *)bl)->class].size;
- else
- return 1;
-}
-int battle_get_mode(struct block_list *bl)
-{
- nullpo_retr(0x01, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return mob_db[((struct mob_data *)bl)->class].mode;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- return mob_db[((struct pet_data *)bl)->class].mode;
- else
- return 0x01; // ‚Ƃ肠‚¦‚¸“®‚­‚Æ‚¢‚¤‚±‚Æ‚Å1
-}
-
-int battle_get_mexp(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return mob_db[((struct mob_data *)bl)->class].mexp;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- return mob_db[((struct pet_data *)bl)->class].mexp;
- else
- return 0;
-}
-
-// StatusChangeŒn‚ÌŠ“¾
-struct status_change *battle_get_sc_data(struct block_list *bl)
-{
- nullpo_retr(NULL, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return ((struct mob_data*)bl)->sc_data;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data*)bl)->sc_data;
- return NULL;
-}
-short *battle_get_sc_count(struct block_list *bl)
-{
- nullpo_retr(NULL, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return &((struct mob_data*)bl)->sc_count;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return &((struct map_session_data*)bl)->sc_count;
- return NULL;
-}
-short *battle_get_opt1(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return &((struct mob_data*)bl)->opt1;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return &((struct map_session_data*)bl)->opt1;
- else if(bl->type==BL_NPC && (struct npc_data *)bl)
- return &((struct npc_data*)bl)->opt1;
- return 0;
-}
-short *battle_get_opt2(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return &((struct mob_data*)bl)->opt2;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return &((struct map_session_data*)bl)->opt2;
- else if(bl->type==BL_NPC && (struct npc_data *)bl)
- return &((struct npc_data*)bl)->opt2;
- return 0;
-}
-short *battle_get_opt3(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return &((struct mob_data*)bl)->opt3;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return &((struct map_session_data*)bl)->opt3;
- else if(bl->type==BL_NPC && (struct npc_data *)bl)
- return &((struct npc_data*)bl)->opt3;
- return 0;
-}
-short *battle_get_option(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return &((struct mob_data*)bl)->option;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return &((struct map_session_data*)bl)->status.option;
- else if(bl->type==BL_NPC && (struct npc_data *)bl)
- return &((struct npc_data*)bl)->option;
- return 0;
-}
-
-//-------------------------------------------------------------------
// ƒ_ƒ[ƒW‚Ì’x‰„
struct battle_delay_damage_ {
- struct block_list *src,*target;
+ struct block_list *src;
+ int target;
int damage;
int flag;
};
int battle_delay_damage_sub(int tid,unsigned int tick,int id,int data)
{
struct battle_delay_damage_ *dat=(struct battle_delay_damage_ *)data;
- if( dat && map_id2bl(id)==dat->src && dat->target->prev!=NULL)
- battle_damage(dat->src,dat->target,dat->damage,dat->flag);
- free(dat);
+ struct block_list *target=map_id2bl(dat->target);
+ if( dat && map_id2bl(id)==dat->src && target && target->prev!=NULL)
+ battle_damage(dat->src,target,dat->damage,dat->flag);
+ aFree(dat);
return 0;
}
int battle_delay_damage(unsigned int tick,struct block_list *src,struct block_list *target,int damage,int flag)
@@ -1319,7 +82,7 @@ int battle_delay_damage(unsigned int tick,struct block_list *src,struct block_li
dat->src=src;
- dat->target=target;
+ dat->target=target->id;
dat->damage=damage;
dat->flag=flag;
add_timer(tick,battle_delay_damage_sub,src->id,(int)dat);
@@ -1330,7 +93,7 @@ int battle_delay_damage(unsigned int tick,struct block_list *src,struct block_li
int battle_damage(struct block_list *bl,struct block_list *target,int damage,int flag)
{
struct map_session_data *sd=NULL;
- struct status_change *sc_data=battle_get_sc_data(target);
+ struct status_change *sc_data=status_get_sc_data(target);
short *sc_count;
int i;
@@ -1353,14 +116,14 @@ int battle_damage(struct block_list *bl,struct block_list *target,int damage,int
if(damage<0)
return battle_heal(bl,target,-damage,0,flag);
- if(!flag && (sc_count=battle_get_sc_count(target))!=NULL && *sc_count>0){
+ if(!flag && (sc_count=status_get_sc_count(target))!=NULL && *sc_count>0){
// “€Œ‹AΉ»A‡–°‚ðÁ‹Ž
if(sc_data[SC_FREEZE].timer!=-1)
- skill_status_change_end(target,SC_FREEZE,-1);
+ status_change_end(target,SC_FREEZE,-1);
if(sc_data[SC_STONE].timer!=-1 && sc_data[SC_STONE].val2==0)
- skill_status_change_end(target,SC_STONE,-1);
+ status_change_end(target,SC_STONE,-1);
if(sc_data[SC_SLEEP].timer!=-1)
- skill_status_change_end(target,SC_SLEEP,-1);
+ status_change_end(target,SC_SLEEP,-1);
}
if(target->type==BL_MOB){ // MOB
@@ -1479,29 +242,35 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
struct mob_data *md=NULL;
struct status_change *sc_data,*sc;
short *sc_count;
- int class;
+ int class_;
nullpo_retr(0, bl);
- class = battle_get_class(bl);
+ class_ = status_get_class(bl);
if(bl->type==BL_MOB) md=(struct mob_data *)bl;
else sd=(struct map_session_data *)bl;
- sc_data=battle_get_sc_data(bl);
- sc_count=battle_get_sc_count(bl);
+ sc_data=status_get_sc_data(bl);
+ sc_count=status_get_sc_count(bl);
if(sc_count!=NULL && *sc_count>0){
-
- if(sc_data[SC_SAFETYWALL].timer!=-1 && damage>0 && flag&BF_WEAPON && flag&BF_SHORT && skill_num != NPC_GUIDEDATTACK){
+ if (sc_data[SC_SAFETYWALL].timer!=-1 && damage>0 && flag&BF_WEAPON &&
+ flag&BF_SHORT && skill_num != NPC_GUIDEDATTACK) {
// ƒZ[ƒtƒeƒBƒEƒH[ƒ‹
- struct skill_unit *unit=(struct skill_unit*)sc_data[SC_SAFETYWALL].val2;
- if( unit && unit->alive && (--unit->group->val2)<=0 )
- skill_delunit(unit);
- skill_unit_move(bl,gettick(),1); // d‚ËŠ|‚¯ƒ`ƒFƒbƒN
- damage=0;
+ struct skill_unit *unit;
+ unit = (struct skill_unit *)sc_data[SC_SAFETYWALL].val2;
+ if (unit) {
+ if (unit->group && (--unit->group->val2)<=0)
+ skill_delunit(unit);
+ damage=0;
+ } else {
+ status_change_end(bl,SC_SAFETYWALL,-1);
+ }
}
- if(sc_data[SC_PNEUMA].timer!=-1 && damage>0 && ((flag&BF_WEAPON && flag&BF_LONG && skill_num != NPC_GUIDEDATTACK) ||
- (flag&BF_MISC && (skill_num == HT_BLITZBEAT || skill_num == SN_FALCONASSAULT)))){ // [DracoRPG]
+ if(sc_data[SC_PNEUMA].timer!=-1 && damage>0 &&
+ ((flag&BF_WEAPON && flag&BF_LONG && skill_num != NPC_GUIDEDATTACK) ||
+ (flag&BF_MISC && (skill_num == HT_BLITZBEAT || skill_num == SN_FALCONASSAULT)) ||
+ (flag&BF_MAGIC && skill_num == ASC_BREAKER))){ // [DracoRPG]
// ƒjƒ…[ƒ}
damage=0;
}
@@ -1514,29 +283,35 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
if(sc_data[SC_AETERNA].timer!=-1 && damage>0){ // ƒŒƒbƒNƒXƒG[ƒeƒ‹ƒi
damage<<=1;
- skill_status_change_end( bl,SC_AETERNA,-1 );
+ status_change_end( bl,SC_AETERNA,-1 );
}
//‘®«ê‚̃_ƒ[ƒW‘‰Á
if(sc_data[SC_VOLCANO].timer!=-1){ // ƒ{ƒ‹ƒP[ƒm
if(flag&BF_SKILL && skill_get_pl(skill_num)==3)
- damage += damage*sc_data[SC_VOLCANO].val4/100;
- else if(!flag&BF_SKILL && battle_get_attack_element(bl)==3)
- damage += damage*sc_data[SC_VOLCANO].val4/100;
+ //damage += damage*sc_data[SC_VOLCANO].val4/100;
+ damage += damage * enchant_eff[sc_data[SC_VOLCANO].val1-1] /100;
+ else if(!flag&BF_SKILL && status_get_attack_element(bl)==3)
+ //damage += damage*sc_data[SC_VOLCANO].val4/100;
+ damage += damage * enchant_eff[sc_data[SC_VOLCANO].val1-1] /100;
}
if(sc_data[SC_VIOLENTGALE].timer!=-1){ // ƒoƒCƒIƒŒƒ“ƒgƒQƒCƒ‹
if(flag&BF_SKILL && skill_get_pl(skill_num)==4)
- damage += damage*sc_data[SC_VIOLENTGALE].val4/100;
- else if(!flag&BF_SKILL && battle_get_attack_element(bl)==4)
- damage += damage*sc_data[SC_VIOLENTGALE].val4/100;
+ //damage += damage*sc_data[SC_VIOLENTGALE].val4/100;
+ damage += damage * enchant_eff[sc_data[SC_VIOLENTGALE].val1-1] /100;
+ else if(!flag&BF_SKILL && status_get_attack_element(bl)==4)
+ //damage += damage*sc_data[SC_VIOLENTGALE].val4/100;
+ damage += damage * enchant_eff[sc_data[SC_VIOLENTGALE].val1-1] /100;
}
if(sc_data[SC_DELUGE].timer!=-1){ // ƒfƒŠƒ…[ƒW
if(flag&BF_SKILL && skill_get_pl(skill_num)==1)
- damage += damage*sc_data[SC_DELUGE].val4/100;
- else if(!flag&BF_SKILL && battle_get_attack_element(bl)==1)
- damage += damage*sc_data[SC_DELUGE].val4/100;
+ //damage += damage*sc_data[SC_DELUGE].val4/100;
+ damage += damage * enchant_eff[sc_data[SC_DELUGE].val1-1] /100;
+ else if(!flag&BF_SKILL && status_get_attack_element(bl)==1)
+ //damage += damage*sc_data[SC_DELUGE].val4/100;
+ damage += damage * enchant_eff[sc_data[SC_DELUGE].val1-1] /100;
}
if(sc_data[SC_ENERGYCOAT].timer!=-1 && damage>0 && flag&BF_WEAPON){ // ƒGƒiƒW[ƒR[ƒg
@@ -1549,7 +324,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
clif_updatestatus(sd,SP_SP);
}
if(sd->status.sp<=0)
- skill_status_change_end( bl,SC_ENERGYCOAT,-1 );
+ status_change_end( bl,SC_ENERGYCOAT,-1 );
}
else
damage -= damage * (sc_data[SC_ENERGYCOAT].val1 * 6) / 100;
@@ -1563,7 +338,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
else damage=-sc->val2;
}
if((--sc->val3)<=0 || (sc->val2<=0) || skill_num == AL_HOLYLIGHT)
- skill_status_change_end(bl, SC_KYRIE, -1);
+ status_change_end(bl, SC_KYRIE, -1);
}
if(sc_data[SC_BASILICA].timer!=-1 && damage > 0){
@@ -1577,12 +352,21 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
if(sc_data[SC_AUTOGUARD].timer != -1 && damage > 0 && flag&BF_WEAPON) {
if(rand()%100 < sc_data[SC_AUTOGUARD].val2) {
+ int delay;
+
damage = 0;
clif_skill_nodamage(bl,bl,CR_AUTOGUARD,sc_data[SC_AUTOGUARD].val1,1);
+ // different delay depending on skill level [celest]
+ if (sc_data[SC_AUTOGUARD].val1 <= 5)
+ delay = 300;
+ else if (sc_data[SC_AUTOGUARD].val1 > 5 && sc_data[SC_AUTOGUARD].val1 <= 9)
+ delay = 200;
+ else
+ delay = 100;
if(sd)
- sd->canmove_tick = gettick() + 300;
+ sd->canmove_tick = gettick() + delay;
else if(md)
- md->canmove_tick = gettick() + 300;
+ md->canmove_tick = gettick() + delay;
}
}
// -- moonsoul (chance to block attacks with new Lord Knight skill parrying)
@@ -1595,39 +379,43 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
}
// ƒŠƒWƒFƒNƒgƒ\[ƒh
if(sc_data[SC_REJECTSWORD].timer!=-1 && damage > 0 && flag&BF_WEAPON &&
- ((src->type==BL_PC && ((struct map_session_data *)src)->status.weapon == (1 || 2 || 3)) || src->type==BL_MOB )){
+ // Fixed the condition check [Aalye]
+ (src->type==BL_MOB || (src->type==BL_PC && (((struct map_session_data *)src)->status.weapon == 1 ||
+ ((struct map_session_data *)src)->status.weapon == 2 ||
+ ((struct map_session_data *)src)->status.weapon == 3)))){
if(rand()%100 < (15*sc_data[SC_REJECTSWORD].val1)){ //”½ŽËŠm—¦‚Í15*Lv
damage = damage*50/100;
+ clif_damage(bl,src,gettick(),0,0,damage,0,0,0);
battle_damage(bl,src,damage,0);
//ƒ_ƒ[ƒW‚ð—^‚¦‚½‚̂͗ǂ¢‚ñ‚¾‚ªA‚±‚±‚©‚ç‚Ç‚¤‚µ‚Ä•\ަ‚·‚é‚ñ‚¾‚©‚í‚©‚ñ‚Ë‚¥
//ƒGƒtƒFƒNƒg‚à‚±‚ê‚Å‚¢‚¢‚Ì‚©‚í‚©‚ñ‚Ë‚¥
clif_skill_nodamage(bl,bl,ST_REJECTSWORD,sc_data[SC_REJECTSWORD].val1,1);
if((--sc_data[SC_REJECTSWORD].val2)<=0)
- skill_status_change_end(bl, SC_REJECTSWORD, -1);
+ status_change_end(bl, SC_REJECTSWORD, -1);
}
}
if(sc_data[SC_SPIDERWEB].timer!=-1 && damage > 0) // [Celest]
if ((flag&BF_SKILL && skill_get_pl(skill_num)==3) ||
- (!flag&BF_SKILL && battle_get_attack_element(src)==3)) {
+ (!flag&BF_SKILL && status_get_attack_element(src)==3)) {
damage<<=1;
- skill_status_change_end(bl, SC_SPIDERWEB, -1);
+ status_change_end(bl, SC_SPIDERWEB, -1);
}
-
+
if(sc_data[SC_FOGWALL].timer != -1 && flag&BF_MAGIC)
- if(rand()%100 < sc_data[SC_FOGWALL].val2)
+ if(rand()%100 < 75)
damage = 0;
}
- if(class == 1288 || class == 1287 || class == 1286 || class == 1285) {
-// if(class == 1288) {
- if(class == 1288 && flag&BF_SKILL)
+ if(class_ == 1288 || class_ == 1287 || class_ == 1286 || class_ == 1285) {
+// if(class_ == 1288) {
+ if(class_ == 1288 && (flag&BF_SKILL || skill_num == ASC_BREAKER || skill_num == PA_SACRIFICE))
damage=0;
if(src->type == BL_PC) {
struct guild *g=guild_search(((struct map_session_data *)src)->status.guild_id);
struct guild_castle *gc=guild_mapname2gc(map[bl->m].name);
if(!((struct map_session_data *)src)->status.guild_id)
damage=0;
- if(gc && agit_flag==0 && class != 1288) // guardians cannot be damaged during non-woe [Valaris]
+ if(gc && agit_flag==0 && class_ != 1288) // guardians cannot be damaged during non-woe [Valaris]
damage=0; // end woe check [Valaris]
if(g == NULL)
damage=0;//ƒMƒ‹ƒh–¢‰Á“ü‚È‚çƒ_ƒ[ƒW–³‚µ
@@ -1636,12 +424,18 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
else if(g && guild_checkskill(g,GD_APPROVAL) <= 0)
damage=0;//³‹KƒMƒ‹ƒh³”F‚ª‚È‚¢‚ƃ_ƒ[ƒW–³‚µ
else if (battle_config.guild_max_castles != 0 && guild_checkcastles(g)>=battle_config.guild_max_castles)
- damage = 0; // [MouseJstr]
+ damage = 0; // [MouseJstr]
+ else if (g && gc && guild_check_alliance(gc->guild_id, g->guild_id, 0) == 1)
+ return 0;
}
else damage = 0;
}
if(map[bl->m].flag.gvg && damage > 0) { //GvG
+ if(bl->type == BL_MOB){ //defense‚ª‚ ‚ê‚΃_ƒ[ƒW‚ªŒ¸‚é‚炵‚¢H
+ struct guild_castle *gc=guild_mapname2gc(map[bl->m].name);
+ if (gc) damage -= damage*(gc->defense/100)*(battle_config.castle_defense_rate/100);
+ }
if(flag&BF_WEAPON) {
if(flag&BF_SHORT)
damage=damage*battle_config.gvg_short_damage_rate/100;
@@ -1671,20 +465,47 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
}
/*==========================================
+ * HP/SP‹zŽû‚ÌŒvŽZ
+ *------------------------------------------
+ */
+int battle_calc_drain(int damage, int rate, int per, int val)
+{
+ int diff = 0;
+
+ if (damage <= 0 || rate <= 0)
+ return 0;
+
+ if (per && rand()%100 < rate) {
+ diff = (damage * per) / 100;
+ if (diff == 0) {
+ if (per > 0)
+ diff = 1;
+ else
+ diff = -1;
+ }
+ }
+
+ if (val && rand()%100 < rate) {
+ diff += val;
+ }
+ return diff;
+}
+
+/*==========================================
* C—ûƒ_ƒ[ƒW
*------------------------------------------
*/
int battle_addmastery(struct map_session_data *sd,struct block_list *target,int dmg,int type)
{
int damage,skill;
- int race=battle_get_race(target);
+ int race=status_get_race(target);
int weapon;
damage = 0;
nullpo_retr(0, sd);
// ƒf[ƒ‚ƒ“ƒxƒCƒ“(+3 ` +30) vs •sŽ€ or ˆ«–‚ (Ž€l‚͊܂߂Ȃ¢H)
- if((skill = pc_checkskill(sd,AL_DEMONBANE)) > 0 && (battle_check_undead(race,battle_get_elem_type(target)) || race==6) )
+ if((skill = pc_checkskill(sd,AL_DEMONBANE)) > 0 && (battle_check_undead(race,status_get_elem_type(target)) || race==6) )
damage += (skill*(int)(3+(sd->status.base_level+1)*0.05)); // submitted by orn
//damage += (skill * 3);
@@ -1698,7 +519,7 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int
weapon = sd->weapontype2;
switch(weapon)
{
- case 0x01: // ’ZŒ• (Updated By AppleGirl)
+ case 0x01: // ’ZŒ• Knife
case 0x02: // 1HS
{
// Œ•C—û(+4 ` +40) •Ў茕 ’ZŒ•ŠÜ‚Þ
@@ -1716,16 +537,6 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int
break;
}
case 0x04: // 1HL
- {
- // ‘„C—û(+4 ` +40,+5 ` +50) ‘„
- if((skill = pc_checkskill(sd,KN_SPEARMASTERY)) > 0) {
- if(!pc_isriding(sd))
- damage += (skill * 4); // ƒyƒR‚Éæ‚Á‚ĂȂ¢
- else
- damage += (skill * 5); // ƒyƒR‚Éæ‚Á‚Ä‚é
- }
- break;
- }
case 0x05: // 2HL
{
// ‘„C—û(+4 ` +40,+5 ` +50) ‘„
@@ -1737,13 +548,7 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int
}
break;
}
- case 0x06: // •ÐŽè•€
- {
- if((skill = pc_checkskill(sd,AM_AXEMASTERY)) > 0) {
- damage += (skill * 3);
- }
- break;
- }
+ case 0x06: // •ÐŽè•€
case 0x07: // Axe by Tato
{
if((skill = pc_checkskill(sd,AM_AXEMASTERY)) > 0) {
@@ -1765,7 +570,7 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int
break;
case 0x0b: // ‹|
break;
- case 0x00: // ‘fŽè
+ case 0x00: // ‘fŽè Bare Hands
case 0x0c: // Knuckles
{
// “SŒ(+3 ` +30) ‘fŽè,ƒiƒbƒNƒ‹
@@ -1819,14 +624,16 @@ static struct Damage battle_calc_pet_weapon_attack(
struct mob_data *tmd=NULL;
int hitrate,flee,cri = 0,atkmin,atkmax;
int luk,target_count = 1;
- int def1 = battle_get_def(target);
- int def2 = battle_get_def2(target);
- int t_vit = battle_get_vit(target);
+ int def1 = status_get_def(target);
+ int def2 = status_get_def2(target);
+ int t_vit = status_get_vit(target);
struct Damage wd;
int damage,damage2=0,type,div_,blewcount=skill_get_blewcount(skill_num,skill_lv);
int flag,dmg_lv=0;
int t_mode=0,t_race=0,t_size=1,s_race=0,s_ele=0;
struct status_change *t_sc_data;
+ int div_flag=0; // 0: total damage is to be divided by div_
+ // 1: damage is distributed,and has to be multiplied by div_ [celest]
//return‘O‚̈—‚ª‚ ‚é‚Ì‚Åî•ño—Í•”‚̂ݕÏX
if( target == NULL || pd == NULL ){ //src‚Í“à—e‚É’¼ÚG‚ê‚Ä‚¢‚È‚¢‚̂ŃXƒ‹[‚µ‚Ă݂é
@@ -1835,8 +642,8 @@ static struct Damage battle_calc_pet_weapon_attack(
return wd;
}
- s_race=battle_get_race(src);
- s_ele=battle_get_attack_element(src);
+ s_race=status_get_race(src);
+ s_ele=status_get_attack_element(src);
// ƒ^[ƒQƒbƒg
if(target->type == BL_MOB)
@@ -1845,61 +652,70 @@ static struct Damage battle_calc_pet_weapon_attack(
memset(&wd,0,sizeof(wd));
return wd;
}
- t_race=battle_get_race( target );
- t_size=battle_get_size( target );
- t_mode=battle_get_mode( target );
- t_sc_data=battle_get_sc_data( target );
+ t_race=status_get_race( target );
+ t_size=status_get_size( target );
+ t_mode=status_get_mode( target );
+ t_sc_data=status_get_sc_data( target );
flag=BF_SHORT|BF_WEAPON|BF_NORMAL; // UŒ‚‚ÌŽí—Þ‚ÌÝ’è
// ‰ñ”𗦌vŽZA‰ñ”ð”»’è‚ÍŒã‚Å
- flee = battle_get_flee(target);
- if(battle_config.agi_penaly_type > 0 || battle_config.vit_penaly_type > 0)
- target_count += battle_counttargeted(target,src,battle_config.agi_penaly_count_lv);
- if(battle_config.agi_penaly_type > 0) {
- if(target_count >= battle_config.agi_penaly_count) {
- if(battle_config.agi_penaly_type == 1)
- flee = (flee * (100 - (target_count - (battle_config.agi_penaly_count - 1))*battle_config.agi_penaly_num))/100;
- else if(battle_config.agi_penaly_type == 2)
- flee -= (target_count - (battle_config.agi_penaly_count - 1))*battle_config.agi_penaly_num;
+ flee = status_get_flee(target);
+ if(battle_config.agi_penalty_type > 0 || battle_config.vit_penalty_type > 0)
+ target_count += battle_counttargeted(target,src,battle_config.agi_penalty_count_lv);
+ if(battle_config.agi_penalty_type > 0) {
+ if(target_count >= battle_config.agi_penalty_count) {
+ if(battle_config.agi_penalty_type == 1)
+ flee = (flee * (100 - (target_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100;
+ else if(battle_config.agi_penalty_type == 2)
+ flee -= (target_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num;
if(flee < 1) flee = 1;
}
}
- hitrate=battle_get_hit(src) - flee + 80;
+ hitrate=status_get_hit(src) - flee + 80;
type=0; // normal
- div_ = 1; // single attack
+ if (skill_num > 0) {
+ div_ = skill_get_num(skill_num,skill_lv);
+ if (div_ < 1) div_ = 1; //Avoid the rare case where the db says div_ is 0 and below
+ }
+ else div_ = 1; // single attack
- luk=battle_get_luk(src);
+ luk=status_get_luk(src);
if(battle_config.pet_str)
- damage = battle_get_baseatk(src);
+ damage = status_get_baseatk(src);
else
damage = 0;
if(skill_num==HW_MAGICCRASHER){ /* ƒ}ƒWƒbƒNƒNƒ‰ƒbƒVƒƒ[‚ÍMATK‚ʼn£‚é */
- atkmin = battle_get_matk1(src);
- atkmax = battle_get_matk2(src);
+ atkmin = status_get_matk1(src);
+ atkmax = status_get_matk2(src);
}else{
- atkmin = battle_get_atk(src);
- atkmax = battle_get_atk2(src);
+ atkmin = status_get_atk(src);
+ atkmax = status_get_atk2(src);
}
- if(mob_db[pd->class].range>3 )
+ if(mob_db[pd->class_].range>3 )
flag=(flag&~BF_RANGEMASK)|BF_LONG;
if(atkmin > atkmax) atkmin = atkmax;
- cri = battle_get_critical(src);
- cri -= battle_get_luk(target) * 2; // luk/5*10 => target_luk*2 not target_luk*3
+ cri = status_get_critical(src);
+ cri -= status_get_luk(target) * 2; // luk/5*10 => target_luk*2 not target_luk*3
if(battle_config.enemy_critical_rate != 100) {
cri = cri*battle_config.enemy_critical_rate/100;
if(cri < 1)
cri = 1;
}
- if(t_sc_data != NULL && t_sc_data[SC_SLEEP].timer!=-1 )
- cri <<=1;
+ if(t_sc_data) {
+ if (t_sc_data[SC_SLEEP].timer!=-1)
+ cri <<=1;
+ if(t_sc_data[SC_JOINTBEAT].timer != -1 &&
+ t_sc_data[SC_JOINTBEAT].val2 == 6) // Always take crits with Neck broken by Joint Beat [DracoRPG]
+ cri = 1000;
+ }
- if(skill_num == 0 && skill_lv >= 0 && battle_config.enemy_critical && (rand() % 1000) < cri)
+ if(skill_num == 0 && battle_config.enemy_critical && (rand() % 1000) < cri)
{
damage += atkmax;
type = 0x0a;
@@ -1930,14 +746,14 @@ static struct Damage battle_calc_pet_weapon_attack(
hitrate = (hitrate*(100+5*skill_lv))/100;
break;
case SM_MAGNUM: // ƒ}ƒOƒiƒ€ƒuƒŒƒCƒN
- damage = damage*(5*skill_lv +(wflag)?65:115 )/100;
+ damage = damage*(wflag > 1 ? 5*skill_lv+115 : 30*skill_lv+100)/100;
+ hitrate = (hitrate*(100+10*skill_lv))/100;
break;
case MC_MAMMONITE: // ƒƒ}[ƒiƒCƒg
damage = damage*(100+ 50*skill_lv)/100;
break;
case AC_DOUBLE: // ƒ_ƒuƒ‹ƒXƒgƒŒƒCƒtƒBƒ“ƒO
damage = damage*(180+ 20*skill_lv)/100;
- div_=2;
flag=(flag&~BF_RANGEMASK)|BF_LONG;
break;
case AC_SHOWER: // ƒAƒ[ƒVƒƒƒ[
@@ -1952,7 +768,7 @@ static struct Damage battle_calc_pet_weapon_attack(
damage = damage*(100+ 10*skill_lv)/100;
hitrate = hitrate*(100+5*skill_lv)/100;
div_=t_size+1;
- damage*=div_;
+ div_flag = 1;
break;
case KN_SPEARSTAB: // ƒXƒsƒAƒXƒ^ƒu
damage = damage*(100+ 15*skill_lv)/100;
@@ -1970,14 +786,13 @@ static struct Damage battle_calc_pet_weapon_attack(
if(skill_lv>9 && wflag==2) damage2+=damage/4;
if(skill_lv>9 && wflag==3) damage2+=damage/2;
damage +=damage2;
- blewcount=0;
break;
case KN_BOWLINGBASH: // ƒ{ƒEƒŠƒ“ƒOƒoƒbƒVƒ…
damage = damage*(100+ 50*skill_lv)/100;
blewcount=0;
break;
case AS_GRIMTOOTH:
- damage = damage*(100+ 20*skill_lv)/100;
+ damage = damage*(100+ 20*skill_lv)/100;
break;
case AS_POISONREACT: // celest
s_ele = 0;
@@ -1985,7 +800,6 @@ static struct Damage battle_calc_pet_weapon_attack(
break;
case AS_SONICBLOW: // ƒ\ƒjƒbƒNƒuƒƒE
damage = damage*(300+ 50*skill_lv)/100;
- div_=8;
break;
case TF_SPRINKLESAND: // »‚Ü‚«
damage = damage*125/100;
@@ -1995,8 +809,7 @@ static struct Damage battle_calc_pet_weapon_attack(
break;
// ˆÈ‰ºMOB
case NPC_COMBOATTACK: // ‘½’iUŒ‚
- div_=skill_get_num(skill_num,skill_lv);
- damage *= div_;
+ div_flag = 1;
break;
case NPC_RANDOMATTACK: // ƒ‰ƒ“ƒ_ƒ€ATKUŒ‚
damage = damage*(50+rand()%150)/100;
@@ -2009,6 +822,7 @@ static struct Damage battle_calc_pet_weapon_attack(
case NPC_POISONATTACK:
case NPC_HOLYATTACK:
case NPC_DARKNESSATTACK:
+ case NPC_UNDEADATTACK:
case NPC_TELEKINESISATTACK:
div_= pd->skillduration; // [Valaris]
break;
@@ -2043,27 +857,27 @@ static struct Damage battle_calc_pet_weapon_attack(
break;
case CR_HOLYCROSS: // ƒz[ƒŠ[ƒNƒƒX
damage = damage*(100+ 35*skill_lv)/100;
- div_=2;
break;
case CR_GRANDCROSS:
hitrate= 1000000;
break;
case AM_DEMONSTRATION: // ƒfƒ‚ƒ“ƒXƒgƒŒ[ƒVƒ‡ƒ“
+ hitrate= 1000000;
damage = damage*(100+ 20*skill_lv)/100;
damage2 = damage2*(100+ 20*skill_lv)/100;
break;
case AM_ACIDTERROR: // ƒAƒVƒbƒhƒeƒ‰[
+ hitrate = 1000000;
damage = damage*(100+ 40*skill_lv)/100;
damage2 = damage2*(100+ 40*skill_lv)/100;
break;
case MO_FINGEROFFENSIVE: //Žw’e
damage = damage * (125 + 25 * skill_lv) / 100;
- div_ = 1;
flag=(flag&~BF_RANGEMASK)|BF_LONG; //orn
break;
case MO_INVESTIGATE: // ”­ ™¤
if(def1 < 1000000)
- damage = damage*(100+ 75*skill_lv)/100 * (def1 + def2)/100;
+ damage = damage*(100+ 75*skill_lv)/100 * (def1 + def2)/50;
hitrate = 1000000;
s_ele = 0;
break;
@@ -2074,32 +888,30 @@ static struct Damage battle_calc_pet_weapon_attack(
break;
case MO_CHAINCOMBO: // ˜A‘Ŷ
damage = damage*(150+ 50*skill_lv)/100;
- div_=4;
break;
case MO_COMBOFINISH: // –Ò—´Œ
damage = damage*(240+ 60*skill_lv)/100;
break;
case DC_THROWARROW: // –‚¿
- damage = damage*(100+ 50 * skill_lv)/100;
+ damage = damage*(60+ 40 * skill_lv)/100;
flag=(flag&~BF_RANGEMASK)|BF_LONG;
break;
case BA_MUSICALSTRIKE: // ƒ~ƒ…[ƒWƒJƒ‹ƒXƒgƒ‰ƒCƒN
- damage = damage*(100+ 50 * skill_lv)/100;
+ damage = damage*(60+ 40 * skill_lv)/100;
flag=(flag&~BF_RANGEMASK)|BF_LONG;
break;
case CH_TIGERFIST: // •šŒÕŒ
- damage = damage*(100+ 60*skill_lv)/100;
+ damage = damage*(40+ 100*skill_lv)/100;
break;
case CH_CHAINCRUSH: // ˜A’Œ•öŒ‚
- damage = damage*(100+ 60*skill_lv)/100;
- div_=skill_get_num(skill_num,skill_lv);
+ damage = damage*(400+ 100*skill_lv)/100;
break;
case CH_PALMSTRIKE: // –ÒŒÕd”hŽR
- damage = damage*(50+ 100*skill_lv)/100;
+ damage = damage*(200+ 100*skill_lv)/100;
break;
case LK_SPIRALPIERCE: /* ƒXƒpƒCƒ‰ƒ‹ƒsƒA[ƒX */
damage = damage*(100+ 50*skill_lv)/100; //‘‰Á—Ê‚ª•ª‚©‚ç‚È‚¢‚̂œK“–‚É
- div_=5;
+ flag=(flag&~BF_RANGEMASK)|BF_LONG;
if(target->type == BL_PC)
((struct map_session_data *)target)->canmove_tick = gettick() + 1000;
else if(target->type == BL_MOB)
@@ -2119,31 +931,35 @@ static struct Damage battle_calc_pet_weapon_attack(
break;
case CG_ARROWVULCAN: /* ƒAƒ[ƒoƒ‹ƒJƒ“ */
damage = damage*(200+100*skill_lv)/100;
- div_=9;
break;
case AS_SPLASHER: /* ƒxƒiƒ€ƒXƒvƒ‰ƒbƒVƒƒ[ */
damage = damage*(200+20*skill_lv)/100;
+ hitrate = 1000000;
break;
}
+ if (div_flag && div_ > 1) { // [Skotlex]
+ damage *= div_;
+ damage2 *= div_;
+ }
}
if( skill_num!=NPC_CRITICALSLASH ){
// ‘Î Û‚Ì–hŒä—͂ɂæ‚éƒ_ƒ[ƒW‚ÌŒ¸­
// ƒfƒBƒoƒCƒ“ƒvƒƒeƒNƒVƒ‡ƒ“i‚±‚±‚Å‚¢‚¢‚Ì‚©‚ÈHj
- if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && def1 < 1000000 ) { //DEF, VIT–³Ž‹
+ if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && skill_num != AM_ACIDTERROR && def1 < 1000000 ) { //DEF, VIT–³Ž‹
int t_def;
- target_count = 1 + battle_counttargeted(target,src,battle_config.vit_penaly_count_lv);
- if(battle_config.vit_penaly_type > 0) {
- if(target_count >= battle_config.vit_penaly_count) {
- if(battle_config.vit_penaly_type == 1) {
- def1 = (def1 * (100 - (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num))/100;
- def2 = (def2 * (100 - (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num))/100;
- t_vit = (t_vit * (100 - (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num))/100;
+ target_count = 1 + battle_counttargeted(target,src,battle_config.vit_penalty_count_lv);
+ if(battle_config.vit_penalty_type > 0) {
+ if(target_count >= battle_config.vit_penalty_count) {
+ if(battle_config.vit_penalty_type == 1) {
+ def1 = (def1 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100;
+ def2 = (def2 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100;
+ t_vit = (t_vit * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100;
}
- else if(battle_config.vit_penaly_type == 2) {
- def1 -= (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num;
- def2 -= (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num;
- t_vit -= (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num;
+ else if(battle_config.vit_penalty_type == 2) {
+ def1 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num;
+ def2 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num;
+ t_vit -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num;
}
if(def1 < 0) def1 = 0;
if(def2 < 1) def2 = 1;
@@ -2168,10 +984,10 @@ static struct Damage battle_calc_pet_weapon_attack(
// ‰ñ”ðC³
if( hitrate < 1000000 && t_sc_data ) { // •K’†UŒ‚
if(t_sc_data[SC_FOGWALL].timer != -1 && flag&BF_LONG)
- hitrate -= 50;
+ hitrate -= 75;
if (t_sc_data[SC_SLEEP].timer!=-1 || // ‡–°‚Í•K’†
t_sc_data[SC_STAN].timer!=-1 || // ƒXƒ^ƒ“‚Í•K’†
- t_sc_data[SC_FREEZE].timer!=-1 ||
+ t_sc_data[SC_FREEZE].timer!=-1 ||
(t_sc_data[SC_STONE].timer!=-1 && t_sc_data[SC_STONE].val2==0)) // “€Œ‹‚Í•K’†
hitrate = 1000000;
}
@@ -2184,13 +1000,13 @@ static struct Damage battle_calc_pet_weapon_attack(
dmg_lv = ATK_DEF;
}
-
+
if(t_sc_data) {
int cardfix=100;
if(t_sc_data[SC_DEFENDER].timer != -1 && flag&BF_LONG)
cardfix=cardfix*(100-t_sc_data[SC_DEFENDER].val2)/100;
if(t_sc_data[SC_FOGWALL].timer != -1 && flag&BF_LONG)
- cardfix=cardfix*(100-t_sc_data[SC_FOGWALL].val2)/100;
+ cardfix=cardfix*50/100;
if(cardfix != 100)
damage=damage*cardfix/100;
}
@@ -2198,22 +1014,22 @@ static struct Damage battle_calc_pet_weapon_attack(
// ‘® «‚Ì“K—p
if(skill_num != 0 || s_ele != 0 || !battle_config.pet_attack_attr_none)
- damage=battle_attr_fix(damage, s_ele, battle_get_element(target) );
+ damage=battle_attr_fix(damage, s_ele, status_get_element(target) );
if(skill_num==PA_PRESSURE) /* ƒvƒŒƒbƒVƒƒ[ •K’†? */
damage = 500+300*skill_lv;
// ƒCƒ“ƒxƒiƒ€C³
if(skill_num==TF_POISON){
- damage = battle_attr_fix(damage + 15*skill_lv, s_ele, battle_get_element(target) );
+ damage = battle_attr_fix(damage + 15*skill_lv, s_ele, status_get_element(target) );
}
if(skill_num==MC_CARTREVOLUTION){
- damage = battle_attr_fix(damage, 0, battle_get_element(target) );
+ damage = battle_attr_fix(damage, 0, status_get_element(target) );
}
// Š®‘S‰ñ”ð‚Ì”»’è
if(battle_config.enemy_perfect_flee) {
- if(skill_num == 0 && skill_lv >= 0 && tmd!=NULL && rand()%1000 < battle_get_flee2(target) ){
+ if(skill_num == 0 && tmd!=NULL && rand()%1000 < status_get_flee2(target) ){
damage=0;
type=0x0b;
dmg_lv = ATK_LUCKY;
@@ -2231,10 +1047,10 @@ static struct Damage battle_calc_pet_weapon_attack(
wd.damage2=0;
wd.type=type;
wd.div_=div_;
- wd.amotion=battle_get_amotion(src);
+ wd.amotion=status_get_amotion(src);
if(skill_num == KN_AUTOCOUNTER)
wd.amotion >>= 1;
- wd.dmotion=battle_get_dmotion(target);
+ wd.dmotion=status_get_dmotion(target);
wd.blewcount=blewcount;
wd.flag=flag;
wd.dmg_lv=dmg_lv;
@@ -2249,16 +1065,18 @@ static struct Damage battle_calc_mob_weapon_attack(
struct mob_data* md=(struct mob_data *)src,*tmd=NULL;
int hitrate,flee,cri = 0,atkmin,atkmax;
int luk,target_count = 1;
- int def1 = battle_get_def(target);
- int def2 = battle_get_def2(target);
- int t_vit = battle_get_vit(target);
+ int def1 = status_get_def(target);
+ int def2 = status_get_def2(target);
+ int t_vit = status_get_vit(target);
struct Damage wd;
int damage,damage2=0,type,div_,blewcount=skill_get_blewcount(skill_num,skill_lv);
int flag,skill,ac_flag = 0,dmg_lv = 0;
- int t_mode=0,t_race=0,t_size=1,s_race=0,s_ele=0;
+ int t_mode=0,t_race=0,t_size=1,s_race=0,s_ele=0,s_size=0,s_race2=0;
struct status_change *sc_data,*t_sc_data;
short *sc_count;
short *option, *opt1, *opt2;
+ int div_flag=0; // 0: total damage is to be divided by div_
+ // 1: damage is distributed,and has to be multiplied by div_ [celest]
//return‘O‚̈—‚ª‚ ‚é‚Ì‚Åî•ño—Í•”‚̂ݕÏX
if( src == NULL || target == NULL || md == NULL ){
@@ -2267,35 +1085,37 @@ static struct Damage battle_calc_mob_weapon_attack(
return wd;
}
- s_race=battle_get_race(src);
- s_ele=battle_get_attack_element(src);
- sc_data=battle_get_sc_data(src);
- sc_count=battle_get_sc_count(src);
- option=battle_get_option(src);
- opt1=battle_get_opt1(src);
- opt2=battle_get_opt2(src);
+ s_race = status_get_race(src);
+ s_ele = status_get_attack_element(src);
+ s_size = status_get_size(src);
+ sc_data = status_get_sc_data(src);
+ sc_count = status_get_sc_count(src);
+ option = status_get_option(src);
+ opt1 = status_get_opt1(src);
+ opt2 = status_get_opt2(src);
+ s_race2 = status_get_race2(src);
// ƒ^[ƒQƒbƒg
- if(target->type==BL_PC)
- tsd=(struct map_session_data *)target;
- else if(target->type==BL_MOB)
- tmd=(struct mob_data *)target;
- t_race=battle_get_race( target );
- t_size=battle_get_size( target );
- t_mode=battle_get_mode( target );
- t_sc_data=battle_get_sc_data( target );
-
- if((skill_num == 0 || (target->type == BL_PC && battle_config.pc_auto_counter_type&2) ||
- (target->type == BL_MOB && battle_config.monster_auto_counter_type&2)) && skill_lv >= 0) {
+ if(target->type == BL_PC)
+ tsd = (struct map_session_data *)target;
+ else if(target->type == BL_MOB)
+ tmd = (struct mob_data *)target;
+ t_race = status_get_race( target );
+ t_size = status_get_size( target );
+ t_mode = status_get_mode( target );
+ t_sc_data = status_get_sc_data( target );
+
+ if(skill_num == 0 || (target->type == BL_PC && battle_config.pc_auto_counter_type&2) ||
+ (target->type == BL_MOB && battle_config.monster_auto_counter_type&2)) {
if(skill_num != CR_GRANDCROSS && t_sc_data && t_sc_data[SC_AUTOCOUNTER].timer != -1) {
- int dir = map_calc_dir(src,target->x,target->y),t_dir = battle_get_dir(target);
+ int dir = map_calc_dir(src,target->x,target->y),t_dir = status_get_dir(target);
int dist = distance(src->x,src->y,target->x,target->y);
if(dist <= 0 || map_check_dir(dir,t_dir) ) {
memset(&wd,0,sizeof(wd));
t_sc_data[SC_AUTOCOUNTER].val3 = 0;
t_sc_data[SC_AUTOCOUNTER].val4 = 1;
if(sc_data && sc_data[SC_AUTOCOUNTER].timer == -1) {
- int range = battle_get_range(target);
+ int range = status_get_range(target);
if((target->type == BL_PC && ((struct map_session_data *)target)->status.weapon != 11 && dist <= range+1) ||
(target->type == BL_MOB && range <= 3 && dist <= range+1) )
t_sc_data[SC_AUTOCOUNTER].val3 = src->id;
@@ -2312,37 +1132,40 @@ static struct Damage battle_calc_mob_weapon_attack(
flag=BF_SHORT|BF_WEAPON|BF_NORMAL; // UŒ‚‚ÌŽí—Þ‚ÌÝ’è
// ‰ñ”𗦌vŽZA‰ñ”ð”»’è‚ÍŒã‚Å
- flee = battle_get_flee(target);
- if(battle_config.agi_penaly_type > 0 || battle_config.vit_penaly_type > 0)
- target_count += battle_counttargeted(target,src,battle_config.agi_penaly_count_lv);
- if(battle_config.agi_penaly_type > 0) {
- if(target_count >= battle_config.agi_penaly_count) {
- if(battle_config.agi_penaly_type == 1)
- flee = (flee * (100 - (target_count - (battle_config.agi_penaly_count - 1))*battle_config.agi_penaly_num))/100;
- else if(battle_config.agi_penaly_type == 2)
- flee -= (target_count - (battle_config.agi_penaly_count - 1))*battle_config.agi_penaly_num;
+ flee = status_get_flee(target);
+ if(battle_config.agi_penalty_type > 0 || battle_config.vit_penalty_type > 0)
+ target_count += battle_counttargeted(target,src,battle_config.agi_penalty_count_lv);
+ if(battle_config.agi_penalty_type > 0) {
+ if(target_count >= battle_config.agi_penalty_count) {
+ if(battle_config.agi_penalty_type == 1)
+ flee = (flee * (100 - (target_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100;
+ else if(battle_config.agi_penalty_type == 2)
+ flee -= (target_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num;
if(flee < 1) flee = 1;
}
}
- hitrate=battle_get_hit(src) - flee + 80;
+ hitrate=status_get_hit(src) - flee + 80;
type=0; // normal
- div_ = 1; // single attack
+ if (skill_num > 0) {
+ div_ = skill_get_num(skill_num,skill_lv);
+ if (div_ < 1) div_ = 1; //Avoid the rare case where the db says div_ is 0 and below
+ } else div_ = 1; // single attack
- luk=battle_get_luk(src);
+ luk=status_get_luk(src);
if(battle_config.enemy_str)
- damage = battle_get_baseatk(src);
+ damage = status_get_baseatk(src);
else
damage = 0;
if(skill_num==HW_MAGICCRASHER){ /* ƒ}ƒWƒbƒNƒNƒ‰ƒbƒVƒƒ[‚ÍMATK‚ʼn£‚é */
- atkmin = battle_get_matk1(src);
- atkmax = battle_get_matk2(src);
+ atkmin = status_get_matk1(src);
+ atkmax = status_get_matk2(src);
}else{
- atkmin = battle_get_atk(src);
- atkmax = battle_get_atk2(src);
+ atkmin = status_get_atk(src);
+ atkmax = status_get_atk2(src);
}
- if(mob_db[md->class].range>3 )
+ if(mob_db[md->class_].range>3 )
flag=(flag&~BF_RANGEMASK)|BF_LONG;
if(atkmin > atkmax) atkmin = atkmax;
@@ -2351,15 +1174,20 @@ static struct Damage battle_calc_mob_weapon_attack(
atkmin=atkmax;
}
- cri = battle_get_critical(src);
- cri -= battle_get_luk(target) * 3;
+ cri = status_get_critical(src);
+ cri -= status_get_luk(target) * 3;
if(battle_config.enemy_critical_rate != 100) {
cri = cri*battle_config.enemy_critical_rate/100;
if(cri < 1)
cri = 1;
}
- if(t_sc_data != NULL && t_sc_data[SC_SLEEP].timer!=-1 ) // ‡–°’†‚̓NƒŠƒeƒBƒJƒ‹‚ª”{‚É
- cri <<=1;
+ if(t_sc_data) {
+ if (t_sc_data[SC_SLEEP].timer!=-1 ) // ‡–°’†‚̓NƒŠƒeƒBƒJƒ‹‚ª”{‚É
+ cri <<=1;
+ if(t_sc_data[SC_JOINTBEAT].timer != -1 &&
+ t_sc_data[SC_JOINTBEAT].val2 == 6) // Always take crits with Neck broken by Joint Beat [DracoRPG]
+ cri = 1000;
+ }
if(ac_flag) cri = 1000;
@@ -2395,9 +1223,9 @@ static struct Damage battle_calc_mob_weapon_attack(
// ƒ\ƒjƒbƒNƒuƒ[
if(sc_data){ //ó‘ÔˆÙí’†‚̃_ƒ[ƒW’ljÁ
if(sc_data[SC_OVERTHRUST].timer!=-1) // ƒI[ƒo[ƒgƒ‰ƒXƒg
- damage += damage*(5*sc_data[SC_OVERTHRUST].val1)/100;
+ damage += damage*(5*sc_data[SC_OVERTHRUST].val1)/100;
if(sc_data[SC_TRUESIGHT].timer!=-1) // ƒgƒDƒ‹[ƒTƒCƒg
- damage += damage*(2*sc_data[SC_TRUESIGHT].val1)/100;
+ damage += damage*(2*sc_data[SC_TRUESIGHT].val1)/100;
if(sc_data[SC_BERSERK].timer!=-1) // ƒo[ƒT[ƒN
damage += damage*2;
if(sc_data && sc_data[SC_AURABLADE].timer!=-1) //[DracoRPG]
@@ -2416,14 +1244,14 @@ static struct Damage battle_calc_mob_weapon_attack(
hitrate = (hitrate*(100+5*skill_lv))/100;
break;
case SM_MAGNUM: // ƒ}ƒOƒiƒ€ƒuƒŒƒCƒN
- damage = damage*(5*skill_lv +(wflag)?65:115 )/100;
+ damage = damage*(wflag > 1 ? 5*skill_lv+115 : 30*skill_lv+100)/100;
+ hitrate = (hitrate*(100+10*skill_lv))/100;
break;
case MC_MAMMONITE: // ƒƒ}[ƒiƒCƒg
damage = damage*(100+ 50*skill_lv)/100;
break;
case AC_DOUBLE: // ƒ_ƒuƒ‹ƒXƒgƒŒƒCƒtƒBƒ“ƒO
damage = damage*(180+ 20*skill_lv)/100;
- div_=2;
flag=(flag&~BF_RANGEMASK)|BF_LONG;
break;
case AC_SHOWER: // ƒAƒ[ƒVƒƒƒ[
@@ -2436,9 +1264,9 @@ static struct Damage battle_calc_mob_weapon_attack(
break;
case KN_PIERCE: // ƒsƒA[ƒX
damage = damage*(100+ 10*skill_lv)/100;
- hitrate=hitrate*(100+5*skill_lv)/100;
- div_=t_size+1;
- damage*=div_;
+ hitrate = hitrate*(100+5*skill_lv)/100;
+ div_ = t_size+1;
+ div_flag = 1;
break;
case KN_SPEARSTAB: // ƒXƒsƒAƒXƒ^ƒu
damage = damage*(100+ 15*skill_lv)/100;
@@ -2456,7 +1284,6 @@ static struct Damage battle_calc_mob_weapon_attack(
if(skill_lv>9 && wflag==2) damage2+=damage/4;
if(skill_lv>9 && wflag==3) damage2+=damage/2;
damage +=damage2;
- blewcount=0;
break;
case KN_BOWLINGBASH: // ƒ{ƒEƒŠƒ“ƒOƒoƒbƒVƒ…
damage = damage*(100+ 50*skill_lv)/100;
@@ -2470,7 +1297,7 @@ static struct Damage battle_calc_mob_weapon_attack(
flag=(flag&~BF_SKILLMASK)|BF_NORMAL;
break;
case AS_GRIMTOOTH:
- damage = damage*(100+ 20*skill_lv)/100;
+ damage = damage*(100+ 20*skill_lv)/100;
break;
case AS_POISONREACT: // celest
s_ele = 0;
@@ -2478,7 +1305,6 @@ static struct Damage battle_calc_mob_weapon_attack(
break;
case AS_SONICBLOW: // ƒ\ƒjƒbƒNƒuƒƒE
damage = damage*(300+ 50*skill_lv)/100;
- div_=8;
break;
case TF_SPRINKLESAND: // »‚Ü‚«
damage = damage*125/100;
@@ -2488,8 +1314,7 @@ static struct Damage battle_calc_mob_weapon_attack(
break;
// ˆÈ‰ºMOB
case NPC_COMBOATTACK: // ‘½’iUŒ‚
- div_=skill_get_num(skill_num,skill_lv);
- damage *= div_;
+ div_flag = 1;
break;
case NPC_RANDOMATTACK: // ƒ‰ƒ“ƒ_ƒ€ATKUŒ‚
damage = damage*(50+rand()%150)/100;
@@ -2502,6 +1327,7 @@ static struct Damage battle_calc_mob_weapon_attack(
case NPC_POISONATTACK:
case NPC_HOLYATTACK:
case NPC_DARKNESSATTACK:
+ case NPC_UNDEADATTACK:
case NPC_TELEKINESISATTACK:
damage = damage*(100+25*(skill_lv-1))/100;
break;
@@ -2536,27 +1362,27 @@ static struct Damage battle_calc_mob_weapon_attack(
break;
case CR_HOLYCROSS: // ƒz[ƒŠ[ƒNƒƒX
damage = damage*(100+ 35*skill_lv)/100;
- div_=2;
break;
case CR_GRANDCROSS:
hitrate= 1000000;
break;
case AM_DEMONSTRATION: // ƒfƒ‚ƒ“ƒXƒgƒŒ[ƒVƒ‡ƒ“
+ hitrate = 1000000;
damage = damage*(100+ 20*skill_lv)/100;
damage2 = damage2*(100+ 20*skill_lv)/100;
break;
case AM_ACIDTERROR: // ƒAƒVƒbƒhƒeƒ‰[
+ hitrate = 1000000;
damage = damage*(100+ 40*skill_lv)/100;
damage2 = damage2*(100+ 40*skill_lv)/100;
break;
case MO_FINGEROFFENSIVE: //Žw’e
damage = damage * (125 + 25 * skill_lv) / 100;
- div_ = 1;
flag=(flag&~BF_RANGEMASK)|BF_LONG; //orn
break;
case MO_INVESTIGATE: // ”­ ™¤
if(def1 < 1000000)
- damage = damage*(100+ 75*skill_lv)/100 * (def1 + def2)/100;
+ damage = damage*(100+ 75*skill_lv)/100 * (def1 + def2)/50;
hitrate = 1000000;
s_ele = 0;
break;
@@ -2567,32 +1393,30 @@ static struct Damage battle_calc_mob_weapon_attack(
break;
case MO_CHAINCOMBO: // ˜A‘Ŷ
damage = damage*(150+ 50*skill_lv)/100;
- div_=4;
break;
case BA_MUSICALSTRIKE: // ƒ~ƒ…[ƒWƒJƒ‹ƒXƒgƒ‰ƒCƒN
- damage = damage*(100+ 50 * skill_lv)/100;
+ damage = damage*(60+ 40 * skill_lv)/100;
flag=(flag&~BF_RANGEMASK)|BF_LONG;
break;
case DC_THROWARROW: // –‚¿
- damage = damage*(100+ 50 * skill_lv)/100;
+ damage = damage*(60+ 40 * skill_lv)/100;
flag=(flag&~BF_RANGEMASK)|BF_LONG;
break;
case MO_COMBOFINISH: // –Ò—´Œ
damage = damage*(240+ 60*skill_lv)/100;
break;
case CH_TIGERFIST: // •šŒÕŒ
- damage = damage*(100+ 20*skill_lv)/100;
+ damage = damage*(40+ 100*skill_lv)/100;
break;
case CH_CHAINCRUSH: // ˜A’Œ•öŒ‚
- damage = damage*(100+ 60*skill_lv)/100;
- div_=skill_get_num(skill_num,skill_lv);
+ damage = damage*(400+ 100*skill_lv)/100;
break;
case CH_PALMSTRIKE: // –ÒŒÕd”hŽR
- damage = damage*(50+ 100*skill_lv)/100;
+ damage = damage*(200+ 100*skill_lv)/100;
break;
case LK_SPIRALPIERCE: /* ƒXƒpƒCƒ‰ƒ‹ƒsƒA[ƒX */
damage = damage*(100+ 50*skill_lv)/100; //‘‰Á—Ê‚ª•ª‚©‚ç‚È‚¢‚̂œK“–‚É
- div_=5;
+ flag=(flag&~BF_RANGEMASK)|BF_LONG;
if(tsd)
tsd->canmove_tick = gettick() + 1000;
else if(tmd)
@@ -2612,31 +1436,35 @@ static struct Damage battle_calc_mob_weapon_attack(
break;
case CG_ARROWVULCAN: /* ƒAƒ[ƒoƒ‹ƒJƒ“ */
damage = damage*(200+100*skill_lv)/100;
- div_=9;
break;
case AS_SPLASHER: /* ƒxƒiƒ€ƒXƒvƒ‰ƒbƒVƒƒ[ */
damage = damage*(200+20*skill_lv)/100;
+ hitrate = 1000000;
break;
}
+ if (div_flag && div_ > 1) { // [Skotlex]
+ damage *= div_;
+ damage2 *= div_;
+ }
}
if( skill_num!=NPC_CRITICALSLASH ){
// ‘Î Û‚Ì–hŒä—͂ɂæ‚éƒ_ƒ[ƒW‚ÌŒ¸­
// ƒfƒBƒoƒCƒ“ƒvƒƒeƒNƒVƒ‡ƒ“i‚±‚±‚Å‚¢‚¢‚Ì‚©‚ÈHj
- if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && def1 < 1000000) { //DEF, VIT–³Ž‹
+ if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && skill_num != AM_ACIDTERROR && def1 < 1000000) { //DEF, VIT–³Ž‹
int t_def;
- target_count = 1 + battle_counttargeted(target,src,battle_config.vit_penaly_count_lv);
- if(battle_config.vit_penaly_type > 0) {
- if(target_count >= battle_config.vit_penaly_count) {
- if(battle_config.vit_penaly_type == 1) {
- def1 = (def1 * (100 - (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num))/100;
- def2 = (def2 * (100 - (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num))/100;
- t_vit = (t_vit * (100 - (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num))/100;
+ target_count = 1 + battle_counttargeted(target,src,battle_config.vit_penalty_count_lv);
+ if(battle_config.vit_penalty_type > 0) {
+ if(target_count >= battle_config.vit_penalty_count) {
+ if(battle_config.vit_penalty_type == 1) {
+ def1 = (def1 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100;
+ def2 = (def2 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100;
+ t_vit = (t_vit * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100;
}
- else if(battle_config.vit_penaly_type == 2) {
- def1 -= (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num;
- def2 -= (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num;
- t_vit -= (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num;
+ else if(battle_config.vit_penalty_type == 2) {
+ def1 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num;
+ def2 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num;
+ t_vit -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num;
}
if(def1 < 0) def1 = 0;
if(def2 < 1) def2 = 1;
@@ -2644,7 +1472,7 @@ static struct Damage battle_calc_mob_weapon_attack(
}
}
t_def = def2*8/10;
- if(battle_check_undead(s_race,battle_get_elem_type(src)) || s_race==6)
+ if(battle_check_undead(s_race,status_get_elem_type(src)) || s_race==6)
if(tsd && (skill=pc_checkskill(tsd,AL_DP)) > 0 )
t_def += skill* (int) (3 + (tsd->status.base_level+1)*0.04); // submitted by orn
//t_def += skill*3;
@@ -2666,10 +1494,10 @@ static struct Damage battle_calc_mob_weapon_attack(
// ‰ñ”ðC³
if( hitrate < 1000000 && t_sc_data ) { // •K’†UŒ‚
if(t_sc_data[SC_FOGWALL].timer != -1 && flag&BF_LONG)
- hitrate -= 50;
+ hitrate -= 75;
if (t_sc_data[SC_SLEEP].timer!=-1 || // ‡–°‚Í•K’†
t_sc_data[SC_STAN].timer!=-1 || // ƒXƒ^ƒ“‚Í•K’†
- t_sc_data[SC_FREEZE].timer!=-1 ||
+ t_sc_data[SC_FREEZE].timer!=-1 ||
(t_sc_data[SC_STONE].timer!=-1 && t_sc_data[SC_STONE].val2==0)) // “€Œ‹‚Í•K’†
hitrate = 1000000;
}
@@ -2686,16 +1514,24 @@ static struct Damage battle_calc_mob_weapon_attack(
int cardfix=100,i;
cardfix=cardfix*(100-tsd->subele[s_ele])/100; // ‘® «‚É‚æ‚éƒ_ƒ[ƒW‘Ï«
cardfix=cardfix*(100-tsd->subrace[s_race])/100; // Ží‘°‚É‚æ‚éƒ_ƒ[ƒW‘Ï«
- if(mob_db[md->class].mode & 0x20)
+ cardfix=cardfix*(100-tsd->subsize[s_size])/100;
+ cardfix=cardfix*(100-tsd->subrace2[s_race2])/100; // Ží‘°‚É‚æ‚éƒ_ƒ[ƒW‘Ï«
+ if(mob_db[md->class_].mode & 0x20)
cardfix=cardfix*(100-tsd->subrace[10])/100;
else
cardfix=cardfix*(100-tsd->subrace[11])/100;
for(i=0;i<tsd->add_def_class_count;i++) {
- if(tsd->add_def_classid[i] == md->class) {
+ if(tsd->add_def_classid[i] == md->class_) {
cardfix=cardfix*(100-tsd->add_def_classrate[i])/100;
break;
}
}
+ for(i=0;i<tsd->add_damage_class_count2;i++) {
+ if(tsd->add_damage_classid2[i] == md->class_) {
+ cardfix=cardfix*(100+tsd->add_damage_classrate2[i])/100;
+ break;
+ }
+ }
if(flag&BF_LONG)
cardfix=cardfix*(100-tsd->long_attack_def_rate)/100;
if(flag&BF_SHORT)
@@ -2707,7 +1543,7 @@ static struct Damage battle_calc_mob_weapon_attack(
if(t_sc_data[SC_DEFENDER].timer != -1 && flag&BF_LONG)
cardfix=cardfix*(100-t_sc_data[SC_DEFENDER].val2)/100;
if(t_sc_data[SC_FOGWALL].timer != -1 && flag&BF_LONG)
- cardfix=cardfix*(100-t_sc_data[SC_FOGWALL].val2)/100;
+ cardfix=cardfix*50/100;
if(cardfix != 100)
damage=damage*cardfix/100;
}
@@ -2721,11 +1557,11 @@ static struct Damage battle_calc_mob_weapon_attack(
if(damage < 0) damage = 0;
// ‘® «‚Ì“K—p
- if (!((battle_config.mob_ghostring_fix == 1) &&
- (battle_get_element(target) == 8) &&
- (target->type==BL_PC))) // [MouseJstr]
- if(skill_num != 0 || s_ele != 0 || !battle_config.mob_attack_attr_none)
- damage=battle_attr_fix(damage, s_ele, battle_get_element(target) );
+ if (!((battle_config.mob_ghostring_fix == 1) &&
+ (status_get_elem_type(target) == 8) &&
+ (target->type==BL_PC))) // [MouseJstr]
+ if(skill_num != 0 || s_ele != 0 || !battle_config.mob_attack_attr_none)
+ damage=battle_attr_fix(damage, s_ele, status_get_element(target) );
//if(sc_data && sc_data[SC_AURABLADE].timer!=-1) /* ƒI[ƒ‰ƒuƒŒ[ƒh •K’† */
// damage += sc_data[SC_AURABLADE].val1 * 10;
@@ -2734,21 +1570,21 @@ static struct Damage battle_calc_mob_weapon_attack(
// ƒCƒ“ƒxƒiƒ€C³
if(skill_num==TF_POISON){
- damage = battle_attr_fix(damage + 15*skill_lv, s_ele, battle_get_element(target) );
+ damage = battle_attr_fix(damage + 15*skill_lv, s_ele, status_get_element(target) );
}
if(skill_num==MC_CARTREVOLUTION){
- damage = battle_attr_fix(damage, 0, battle_get_element(target) );
+ damage = battle_attr_fix(damage, 0, status_get_element(target) );
}
// Š®‘S‰ñ”ð‚Ì”»’è
- if(skill_num == 0 && skill_lv >= 0 && tsd!=NULL && rand()%1000 < battle_get_flee2(target) ){
+ if(skill_num == 0 && tsd!=NULL && rand()%1000 < status_get_flee2(target) ){
damage=0;
type=0x0b;
dmg_lv = ATK_LUCKY;
}
if(battle_config.enemy_perfect_flee) {
- if(skill_num == 0 && skill_lv >= 0 && tmd!=NULL && rand()%1000 < battle_get_flee2(target) ){
+ if(skill_num == 0 && tmd!=NULL && rand()%1000 < status_get_flee2(target) ){
damage=0;
type=0x0b;
dmg_lv = ATK_LUCKY;
@@ -2769,10 +1605,10 @@ static struct Damage battle_calc_mob_weapon_attack(
wd.damage2=0;
wd.type=type;
wd.div_=div_;
- wd.amotion=battle_get_amotion(src);
+ wd.amotion=status_get_amotion(src);
if(skill_num == KN_AUTOCOUNTER)
wd.amotion >>= 1;
- wd.dmotion=battle_get_dmotion(target);
+ wd.dmotion=status_get_dmotion(target);
wd.blewcount=blewcount;
wd.flag=flag;
wd.dmg_lv=dmg_lv;
@@ -2791,14 +1627,14 @@ static struct Damage battle_calc_pc_weapon_attack(
int hitrate,flee,cri = 0,atkmin,atkmax;
int dex,luk,target_count = 1;
int no_cardfix=0;
- int def1 = battle_get_def(target);
- int def2 = battle_get_def2(target);
-// int mdef1, mdef2;
- int t_vit = battle_get_vit(target);
+ int def1 = status_get_def(target);
+ int def2 = status_get_def2(target);
+ int t_vit = status_get_vit(target);
struct Damage wd;
int damage,damage2,damage3=0,damage4=0,type,div_,blewcount=skill_get_blewcount(skill_num,skill_lv);
int flag,skill,dmg_lv = 0;
- int t_mode=0,t_race=0,t_size=1,s_race=7,s_ele=0;
+ int t_mode=0,t_race=0,t_size=1,s_race=7,s_ele=0,s_size=1;
+ int t_race2=0;
struct status_change *sc_data,*t_sc_data;
short *sc_count;
short *option, *opt1, *opt2;
@@ -2806,6 +1642,8 @@ static struct Damage battle_calc_pc_weapon_attack(
int watk,watk_,cardfix,t_ele;
int da=0,i,t_class,ac_flag = 0;
int idef_flag=0,idef_flag_=0;
+ int div_flag=0; // 0: total damage is to be divided by div_
+ // 1: damage is distributed,and has to be multiplied by div_ [celest]
//return‘O‚̈—‚ª‚ ‚é‚Ì‚Åî•ño—Í•”‚̂ݕÏX
if( src == NULL || target == NULL || sd == NULL ){
@@ -2816,14 +1654,16 @@ static struct Damage battle_calc_pc_weapon_attack(
// ƒAƒ^ƒbƒJ[
- s_race=battle_get_race(src); //Ží‘°
- s_ele=battle_get_attack_element(src); //‘®«
- s_ele_=battle_get_attack_element2(src); //¶Žè‘®«
- sc_data=battle_get_sc_data(src); //ƒXƒe[ƒ^ƒXˆÙí
- sc_count=battle_get_sc_count(src); //ƒXƒe[ƒ^ƒXˆÙí‚Ì”
- option=battle_get_option(src); //‘邯‚©ƒyƒR‚Æ‚©ƒJ[ƒg‚Æ‚©
- opt1=battle_get_opt1(src); //Ή»A“€Œ‹AƒXƒ^ƒ“A‡–°AˆÃˆÅ
- opt2=battle_get_opt2(src); //“ÅAŽô‚¢A’¾–ÙAˆÃˆÅH
+ s_race=status_get_race(src); //Ží‘°
+ s_ele=status_get_attack_element(src); //‘®«
+ s_ele_=status_get_attack_element2(src); //¶Žè‘®«
+ s_size=status_get_size(src);
+ sc_data=status_get_sc_data(src); //ƒXƒe[ƒ^ƒXˆÙí
+ sc_count=status_get_sc_count(src); //ƒXƒe[ƒ^ƒXˆÙí‚Ì”
+ option=status_get_option(src); //‘邯‚©ƒyƒR‚Æ‚©ƒJ[ƒg‚Æ‚©
+ opt1=status_get_opt1(src); //Ή»A“€Œ‹AƒXƒ^ƒ“A‡–°AˆÃˆÅ
+ opt2=status_get_opt2(src); //“ÅAŽô‚¢A’¾–ÙAˆÃˆÅH
+ t_race2=status_get_race2(target);
if(skill_num != CR_GRANDCROSS) //ƒOƒ‰ƒ“ƒhƒNƒƒX‚łȂ¢‚È‚ç
sd->state.attack_type = BF_WEAPON; //UŒ‚ƒ^ƒCƒv‚Í•ŠíUŒ‚
@@ -2833,24 +1673,24 @@ static struct Damage battle_calc_pc_weapon_attack(
tsd=(struct map_session_data *)target; //tsd‚É‘ã“ü(tmd‚ÍNULL)
else if(target->type==BL_MOB) //‘ÎÛ‚ªMob‚È‚ç
tmd=(struct mob_data *)target; //tmd‚É‘ã“ü(tsd‚ÍNULL)
- t_race=battle_get_race( target ); //‘ÎÛ‚ÌŽí‘°
- t_ele=battle_get_elem_type(target); //‘ÎÛ‚Ì‘®«
- t_size=battle_get_size( target ); //‘Îۂ̃TƒCƒY
- t_mode=battle_get_mode( target ); //‘ÎÛ‚ÌMode
- t_sc_data=battle_get_sc_data( target ); //‘Îۂ̃Xƒe[ƒ^ƒXˆÙí
+ t_race=status_get_race( target ); //‘ÎÛ‚ÌŽí‘°
+ t_ele=status_get_elem_type(target); //‘ÎÛ‚Ì‘®«
+ t_size=status_get_size( target ); //‘Îۂ̃TƒCƒY
+ t_mode=status_get_mode( target ); //‘ÎÛ‚ÌMode
+ t_sc_data=status_get_sc_data( target ); //‘Îۂ̃Xƒe[ƒ^ƒXˆÙí
//ƒI[ƒgƒJƒEƒ“ƒ^[ˆ—‚±‚±‚©‚ç
- if((skill_num == 0 || (target->type == BL_PC && battle_config.pc_auto_counter_type&2) ||
- (target->type == BL_MOB && battle_config.monster_auto_counter_type&2)) && skill_lv >= 0) {
+ if(skill_num == 0 || (target->type == BL_PC && battle_config.pc_auto_counter_type&2) ||
+ (target->type == BL_MOB && battle_config.monster_auto_counter_type&2)) {
if(skill_num != CR_GRANDCROSS && t_sc_data && t_sc_data[SC_AUTOCOUNTER].timer != -1) { //ƒOƒ‰ƒ“ƒhƒNƒƒX‚łȂ­A‘ÎÛ‚ªƒI[ƒgƒJƒEƒ“ƒ^[ó‘Ô‚Ìê‡
- int dir = map_calc_dir(src,target->x,target->y),t_dir = battle_get_dir(target);
+ int dir = map_calc_dir(src,target->x,target->y),t_dir = status_get_dir(target);
int dist = distance(src->x,src->y,target->x,target->y);
if(dist <= 0 || map_check_dir(dir,t_dir) ) { //‘ÎۂƂ̋——£‚ª0ˆÈ‰ºA‚Ü‚½‚Í‘Îۂ̳–ÊH
memset(&wd,0,sizeof(wd));
t_sc_data[SC_AUTOCOUNTER].val3 = 0;
t_sc_data[SC_AUTOCOUNTER].val4 = 1;
if(sc_data && sc_data[SC_AUTOCOUNTER].timer == -1) { //Ž©•ª‚ªƒI[ƒgƒJƒEƒ“ƒ^[ó‘Ô
- int range = battle_get_range(target);
+ int range = status_get_range(target);
if((target->type == BL_PC && ((struct map_session_data *)target)->status.weapon != 11 && dist <= range+1) || //‘ÎÛ‚ªPC‚Å•Ší‚ª‹|–Ȃ­ŽË’ö“à
(target->type == BL_MOB && range <= 3 && dist <= range+1) ) //‚Ü‚½‚Í‘ÎÛ‚ªMob‚ÅŽË’ö‚ª3ˆÈ‰º‚ÅŽË’ö“à
t_sc_data[SC_AUTOCOUNTER].val3 = src->id;
@@ -2869,32 +1709,35 @@ static struct Damage battle_calc_pc_weapon_attack(
flag=BF_SHORT|BF_WEAPON|BF_NORMAL; // UŒ‚‚ÌŽí—Þ‚ÌÝ’è
// ‰ñ”𗦌vŽZA‰ñ”ð”»’è‚ÍŒã‚Å
- flee = battle_get_flee(target);
- if(battle_config.agi_penaly_type > 0 || battle_config.vit_penaly_type > 0) //AGIAVITƒyƒiƒ‹ƒeƒBݒ肪—LŒø
- target_count += battle_counttargeted(target,src,battle_config.agi_penaly_count_lv); //‘ÎÛ‚Ì”‚ðŽZo
- if(battle_config.agi_penaly_type > 0) {
- if(target_count >= battle_config.agi_penaly_count) { //ƒyƒiƒ‹ƒeƒBÝ’è‚æ‚è‘ÎÛ‚ª‘½‚¢
- if(battle_config.agi_penaly_type == 1) //‰ñ”𗦂ªagi_penaly_num%‚¸‚ÂŒ¸­
- flee = (flee * (100 - (target_count - (battle_config.agi_penaly_count - 1))*battle_config.agi_penaly_num))/100;
- else if(battle_config.agi_penaly_type == 2) //‰ñ”𗦂ªagi_penaly_num•ªŒ¸­
- flee -= (target_count - (battle_config.agi_penaly_count - 1))*battle_config.agi_penaly_num;
+ flee = status_get_flee(target);
+ if(battle_config.agi_penalty_type > 0 || battle_config.vit_penalty_type > 0) //AGIAVITƒyƒiƒ‹ƒeƒBݒ肪—LŒø
+ target_count += battle_counttargeted(target,src,battle_config.agi_penalty_count_lv); //‘ÎÛ‚Ì”‚ðŽZo
+ if(battle_config.agi_penalty_type > 0) {
+ if(target_count >= battle_config.agi_penalty_count) { //ƒyƒiƒ‹ƒeƒBÝ’è‚æ‚è‘ÎÛ‚ª‘½‚¢
+ if(battle_config.agi_penalty_type == 1) //‰ñ”𗦂ªagi_penalty_num%‚¸‚ÂŒ¸­
+ flee = (flee * (100 - (target_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100;
+ else if(battle_config.agi_penalty_type == 2) //‰ñ”𗦂ªagi_penalty_num•ªŒ¸­
+ flee -= (target_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num;
if(flee < 1) flee = 1; //‰ñ”𗦂ÍÅ’á‚Å‚à1
}
}
- hitrate=battle_get_hit(src) - flee + 80; //–½’†—¦ŒvŽZ
+ hitrate=status_get_hit(src) - flee + 80; //–½’†—¦ŒvŽZ
type=0; // normal
- div_ = 1; // single attack
+ if (skill_num > 0) {
+ div_=skill_get_num(skill_num,skill_lv);
+ if (div_ < 1) div_ = 1; //Avoid the rare case where the db says div_ is 0 and below
+ } else div_ = 1; // single attack
- dex=battle_get_dex(src); //DEX
- luk=battle_get_luk(src); //LUK
- watk = battle_get_atk(src); //ATK
- watk_ = battle_get_atk_(src); //ATK¶Žè
+ dex=status_get_dex(src); //DEX
+ luk=status_get_luk(src); //LUK
+ watk = status_get_atk(src); //ATK
+ watk_ = status_get_atk_(src); //ATK¶Žè
if(skill_num==HW_MAGICCRASHER){ /* ƒ}ƒWƒbƒNƒNƒ‰ƒbƒVƒƒ[‚ÍMATK‚ʼn£‚é */
- damage = damage2 = battle_get_matk1(src); //damega,damega2‰“oêAbase_atk‚̎擾
+ damage = damage2 = status_get_matk1(src); //damega,damega2‰“oêAbase_atk‚̎擾
}else{
- damage = damage2 = battle_get_baseatk(&sd->bl); //damega,damega2‰“oêAbase_atk‚̎擾
+ damage = damage2 = status_get_baseatk(&sd->bl); //damega,damega2‰“oêAbase_atk‚̎擾
}
atkmin = atkmin_ = dex; //Å’áATK‚ÍDEX‚ʼnŠú‰»H
sd->state.arrow_atk = 0; //arrow_atk‰Šú‰»
@@ -2942,11 +1785,12 @@ static struct Damage battle_calc_pc_weapon_attack(
}
//ŽO’i¶
- if(skill_num == 0 && skill_lv >= 0 && (skill = pc_checkskill(sd,MO_TRIPLEATTACK)) > 0 && sd->status.weapon <= 16 && !sd->state.arrow_atk) {
+ //if(skill_num == 0 && skill_lv >= 0 && (skill = pc_checkskill(sd,MO_TRIPLEATTACK)) > 0 && sd->status.weapon <= 16 && !sd->state.arrow_atk) {
+ if(skill_num == 0 && (skill = pc_checkskill(sd,MO_TRIPLEATTACK)) > 0 && sd->status.weapon <= 16) { // triple blow works with bows ^^ [celest]
da = (rand()%100 < (30 - skill)) ? 2:0;
}
- if(sd->double_rate > 0 && da == 0 && skill_num == 0 && skill_lv >= 0)
+ if(sd->double_rate > 0 && da == 0 && skill_num == 0)
da = (rand()%100 < sd->double_rate) ? 1:0;
// ‰ß踘Bƒ{[ƒiƒX
@@ -2957,16 +1801,22 @@ static struct Damage battle_calc_pc_weapon_attack(
if(da == 0){ //ƒ_ƒuƒ‹ƒAƒ^ƒbƒN‚ª”­“®‚µ‚Ä‚¢‚È‚¢
// ƒNƒŠƒeƒBƒJƒ‹ŒvŽZ
- cri = battle_get_critical(src);
+ cri = status_get_critical(src);
+ cri += sd->critaddrace[t_race];
if(sd->state.arrow_atk)
cri += sd->arrow_cri;
if(sd->status.weapon == 16)
// ƒJƒ^[ƒ‹‚Ìê‡AƒNƒŠƒeƒBƒJƒ‹‚ð”{‚É
cri <<=1;
- cri -= battle_get_luk(target) * 3;
- if(t_sc_data != NULL && t_sc_data[SC_SLEEP].timer!=-1 ) // ‡–°’†‚̓NƒŠƒeƒBƒJƒ‹‚ª”{‚É
- cri <<=1;
+ cri -= status_get_luk(target) * 3;
+ if(t_sc_data) {
+ if (t_sc_data[SC_SLEEP].timer!=-1 ) // ‡–°’†‚̓NƒŠƒeƒBƒJƒ‹‚ª”{‚É
+ cri <<=1;
+ if(t_sc_data[SC_JOINTBEAT].timer != -1 &&
+ t_sc_data[SC_JOINTBEAT].val2 == 6) // Always take crits with Neck broken by Joint Beat [DracoRPG]
+ cri = 1000;
+ }
if(ac_flag) cri = 1000;
if(skill_num == KN_AUTOCOUNTER) {
@@ -2975,25 +1825,29 @@ static struct Damage battle_calc_pc_weapon_attack(
else
cri <<= 1;
}
-
- if(skill_num == SN_SHARPSHOOTING && rand()%100 < 50)
+ if(skill_num == SN_SHARPSHOOTING)
cri += 200;
}
if(tsd && tsd->critical_def)
cri = cri * (100-tsd->critical_def) / 100;
- if(da == 0 && (skill_num==0 || skill_num == KN_AUTOCOUNTER || skill_num == SN_SHARPSHOOTING) && skill_lv >= 0 && //ƒ_ƒuƒ‹ƒAƒ^ƒbƒN‚ª”­“®‚µ‚Ä‚¢‚È‚¢
+ if(da == 0 && (skill_num==0 || skill_num == KN_AUTOCOUNTER || skill_num == SN_SHARPSHOOTING) && //ƒ_ƒuƒ‹ƒAƒ^ƒbƒN‚ª”­“®‚µ‚Ä‚¢‚È‚¢
(rand() % 1000) < cri) // ”»’èiƒXƒLƒ‹‚Ìꇂ͖³Ž‹j
{
damage += atkmax;
damage2 += atkmax_;
- if(sd->atk_rate != 100) {
- damage = (damage * sd->atk_rate)/100;
- damage2 = (damage2 * sd->atk_rate)/100;
+ if(sd->atk_rate != 100 || sd->weapon_atk_rate != 0) {
+ if (sd->status.weapon < 16) {
+ damage = (damage * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100;
+ damage2 = (damage2 * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100;
+ }
}
if(sd->state.arrow_atk)
damage += sd->arrow_atk;
+
+ damage += damage * sd->crit_atk_rate / 100;
+
type = 0x0a;
/* if(def1 < 1000000) {
@@ -3038,9 +1892,11 @@ static struct Damage battle_calc_pc_weapon_attack(
damage2 += atkmin_ + rand() % (atkmax_-atkmin_ + 1);
else
damage2 += atkmin_ ;
- if(sd->atk_rate != 100) {
- damage = (damage * sd->atk_rate)/100;
- damage2 = (damage2 * sd->atk_rate)/100;
+ if(sd->atk_rate != 100 || sd->weapon_atk_rate != 0) {
+ if (sd->status.weapon < 16) {
+ damage = (damage * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100;
+ damage2 = (damage2 * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100;
+ }
}
if(sd->state.arrow_atk) {
@@ -3119,8 +1975,10 @@ static struct Damage battle_calc_pc_weapon_attack(
hitrate = (hitrate*(100+5*skill_lv))/100;
break;
case SM_MAGNUM: // ƒ}ƒOƒiƒ€ƒuƒŒƒCƒN
- damage = damage*(5*skill_lv +(wflag)?65:115 )/100;
- damage2 = damage2*(5*skill_lv +(wflag)?65:115 )/100;
+ // 20*skill level+100? i think this will do for now [based on jRO info]
+ damage = damage*(wflag > 1 ? 5*skill_lv+115 : 30*skill_lv+100)/100;
+ damage2 = damage2*(wflag > 1 ? 5*skill_lv+115 : 30*skill_lv+100)/100;
+ hitrate = (hitrate*(100+10*skill_lv))/100;
break;
case MC_MAMMONITE: // ƒƒ}[ƒiƒCƒg
damage = damage*(100+ 50*skill_lv)/100;
@@ -3134,7 +1992,6 @@ static struct Damage battle_calc_pc_weapon_attack(
}
damage = damage*(180+ 20*skill_lv)/100;
damage2 = damage2*(180+ 20*skill_lv)/100;
- div_=2;
if(sd->arrow_ele > 0) {
s_ele = sd->arrow_ele;
s_ele_ = sd->arrow_ele;
@@ -3177,12 +2034,12 @@ static struct Damage battle_calc_pc_weapon_attack(
damage2 = damage2*(100+ 10*skill_lv)/100;
hitrate=hitrate*(100+5*skill_lv)/100;
div_=t_size+1;
- damage*=div_;
- damage2*=div_;
+ div_flag=1;
break;
case KN_SPEARSTAB: // ƒXƒsƒAƒXƒ^ƒu
damage = damage*(100+ 15*skill_lv)/100;
damage2 = damage2*(100+ 15*skill_lv)/100;
+ blewcount=0;
break;
case KN_SPEARBOOMERANG: // ƒXƒsƒAƒu[ƒƒ‰ƒ“
damage = damage*(100+ 50*skill_lv)/100;
@@ -3206,7 +2063,6 @@ static struct Damage battle_calc_pc_weapon_attack(
if(skill_lv>9 && wflag==2) damage4+=damage2/4;
if(skill_lv>9 && wflag==3) damage4+=damage2/2;
damage2 +=damage4;
- blewcount=0;
break;
case KN_BOWLINGBASH: // ƒ{ƒEƒŠƒ“ƒOƒoƒbƒVƒ…
damage = damage*(100+ 50*skill_lv)/100;
@@ -3233,7 +2089,6 @@ static struct Damage battle_calc_pc_weapon_attack(
hitrate+=30; // hitrate +30, thanks to midas
damage = damage*(300+ 50*skill_lv)/100;
damage2 = damage2*(300+ 50*skill_lv)/100;
- div_=8;
break;
case TF_SPRINKLESAND: // »‚Ü‚«
damage = damage*125/100;
@@ -3241,8 +2096,10 @@ static struct Damage battle_calc_pc_weapon_attack(
break;
case MC_CARTREVOLUTION: // ƒJ[ƒgƒŒƒ{ƒŠƒ…[ƒVƒ‡ƒ“
if(sd->cart_max_weight > 0 && sd->cart_weight > 0) {
- damage = (damage*(150 + pc_checkskill(sd,BS_WEAPONRESEARCH) + (sd->cart_weight*100/sd->cart_max_weight) ) )/100;
- damage2 = (damage2*(150 + pc_checkskill(sd,BS_WEAPONRESEARCH) + (sd->cart_weight*100/sd->cart_max_weight) ) )/100;
+ damage = ( damage*(150 + sd->cart_weight/800) )/100; //fixed CARTREV damage [Lupus] // should be 800, not 80... weight is *10 ^_- [celest]
+ damage2 = ( damage2*(150 + sd->cart_weight/800) )/100;
+ //damage = (damage*(150 + pc_checkskill(sd,BS_WEAPONRESEARCH) + (sd->cart_weight*100/sd->cart_max_weight) ) )/100;
+ //damage2 = (damage2*(150 + pc_checkskill(sd,BS_WEAPONRESEARCH) + (sd->cart_weight*100/sd->cart_max_weight) ) )/100;
}
else {
damage = (damage*150)/100;
@@ -3251,9 +2108,7 @@ static struct Damage battle_calc_pc_weapon_attack(
break;
// ˆÈ‰ºMOB
case NPC_COMBOATTACK: // ‘½’iUŒ‚
- div_=skill_get_num(skill_num,skill_lv);
- damage *= div_;
- damage2 *= div_;
+ div_flag=1;
break;
case NPC_RANDOMATTACK: // ƒ‰ƒ“ƒ_ƒ€ATKUŒ‚
damage = damage*(50+rand()%150)/100;
@@ -3267,6 +2122,7 @@ static struct Damage battle_calc_pc_weapon_attack(
case NPC_POISONATTACK:
case NPC_HOLYATTACK:
case NPC_DARKNESSATTACK:
+ case NPC_UNDEADATTACK:
case NPC_TELEKINESISATTACK:
damage = damage*(100+25*skill_lv)/100;
damage2 = damage2*(100+25*skill_lv)/100;
@@ -3313,7 +2169,6 @@ static struct Damage battle_calc_pc_weapon_attack(
case CR_HOLYCROSS: // ƒz[ƒŠ[ƒNƒƒX
damage = damage*(100+ 35*skill_lv)/100;
damage2 = damage2*(100+ 35*skill_lv)/100;
- div_=2;
break;
case CR_GRANDCROSS:
hitrate= 1000000;
@@ -3324,28 +2179,30 @@ static struct Damage battle_calc_pc_weapon_attack(
case AM_DEMONSTRATION: // ƒfƒ‚ƒ“ƒXƒgƒŒ[ƒVƒ‡ƒ“
damage = damage*(100+ 20*skill_lv)/100;
damage2 = damage2*(100+ 20*skill_lv)/100;
+ no_cardfix = 1;
break;
case AM_ACIDTERROR: // ƒAƒVƒbƒhƒeƒ‰[
+ hitrate = 1000000;
damage = damage*(100+ 40*skill_lv)/100;
damage2 = damage2*(100+ 40*skill_lv)/100;
+ s_ele = 0;
+ s_ele_ = 0;
+ no_cardfix = 1;
break;
case MO_FINGEROFFENSIVE: //Žw’e
+ damage = damage * (125 + 25 * skill_lv) / 100;
+ damage2 = damage2 * (125 + 25 * skill_lv) / 100;
if(battle_config.finger_offensive_type == 0) {
- damage = damage * (125 + 25 * skill_lv) / 100 * sd->spiritball_old;
- damage2 = damage2 * (125 + 25 * skill_lv) / 100 * sd->spiritball_old;
div_ = sd->spiritball_old;
+ div_flag = 1;
}
- else {
- damage = damage * (125 + 25 * skill_lv) / 100;
- damage2 = damage2 * (125 + 25 * skill_lv) / 100;
- div_ = 1;
- }
+ else div_ = 1;
flag=(flag&~BF_RANGEMASK)|BF_LONG; //orn
break;
case MO_INVESTIGATE: // ”­ ™¤
if(def1 < 1000000) {
- damage = damage*(100+ 75*skill_lv)/100 * (def1 + def2)/100;
- damage2 = damage2*(100+ 75*skill_lv)/100 * (def1 + def2)/100;
+ damage = damage*(100+ 75*skill_lv)/100 * (def1 + def2)/50;
+ damage2 = damage2*(100+ 75*skill_lv)/100 * (def1 + def2)/50;
}
hitrate = 1000000;
s_ele = 0;
@@ -3363,26 +2220,19 @@ static struct Damage battle_calc_pc_weapon_attack(
case MO_CHAINCOMBO: // ˜A‘Ŷ
damage = damage*(150+ 50*skill_lv)/100;
damage2 = damage2*(150+ 50*skill_lv)/100;
- div_=4;
break;
case MO_COMBOFINISH: // –Ò—´Œ
damage = damage*(240+ 60*skill_lv)/100;
damage2 = damage2*(240+ 60*skill_lv)/100;
break;
case BA_MUSICALSTRIKE: // ƒ~ƒ…[ƒWƒJƒ‹ƒXƒgƒ‰ƒCƒN
- if(!sd->state.arrow_atk && sd->arrow_atk > 0) {
- int arr = rand()%(sd->arrow_atk+1);
- damage += arr;
- damage2 += arr;
- }
- damage = damage*(100+ 50 * skill_lv)/100;
- damage2 = damage2*(100+ 50 * skill_lv)/100;
+ damage = damage*(60+ 40 * skill_lv)/100;
+ damage2 = damage2*(60+ 40 * skill_lv)/100;
if(sd->arrow_ele > 0) {
s_ele = sd->arrow_ele;
s_ele_ = sd->arrow_ele;
}
flag=(flag&~BF_RANGEMASK)|BF_LONG;
- sd->state.arrow_atk = 1;
break;
case DC_THROWARROW: // –‚¿
if(!sd->state.arrow_atk && sd->arrow_atk > 0) {
@@ -3400,22 +2250,21 @@ static struct Damage battle_calc_pc_weapon_attack(
sd->state.arrow_atk = 1;
break;
case CH_TIGERFIST: // •šŒÕŒ
- damage = damage*(100+ 20*skill_lv)/100;
- damage2 = damage2*(100+ 20*skill_lv)/100;
+ damage = damage*(40+ 100*skill_lv)/100;
+ damage2 = damage*(40+ 100*skill_lv)/100;
break;
case CH_CHAINCRUSH: // ˜A’Œ•öŒ‚
- damage = damage*(100+ 60*skill_lv)/100;
- damage2 = damage2*(100+ 60*skill_lv)/100;
- div_=skill_get_num(skill_num,skill_lv);
+ damage = damage*(400+ 100*skill_lv)/100;
+ damage2 = damage*(400+ 100*skill_lv)/100;
break;
case CH_PALMSTRIKE: // –ÒŒÕd”hŽR
- damage = damage*(50+ 100*skill_lv)/100;
- damage2 = damage2*(50+ 100*skill_lv)/100;
+ damage = damage*(200+ 100*skill_lv)/100;
+ damage2 = damage*(200+ 100*skill_lv)/100;
break;
case LK_SPIRALPIERCE: /* ƒXƒpƒCƒ‰ƒ‹ƒsƒA[ƒX */
damage = damage*(100+ 50*skill_lv)/100; //‘‰Á—Ê‚ª•ª‚©‚ç‚È‚¢‚̂œK“–‚É
damage2 = damage2*(100+ 50*skill_lv)/100; //‘‰Á—Ê‚ª•ª‚©‚ç‚È‚¢‚̂œK“–‚É
- div_=5;
+ flag=(flag&~BF_RANGEMASK)|BF_LONG;
if(tsd)
tsd->canmove_tick = gettick() + 1000;
else if(tmd)
@@ -3441,35 +2290,33 @@ static struct Damage battle_calc_pc_weapon_attack(
case CG_ARROWVULCAN: /* ƒAƒ[ƒoƒ‹ƒJƒ“ */
damage = damage*(200+100*skill_lv)/100;
damage2 = damage2*(200+100*skill_lv)/100;
- div_=9;
+ if(sd->arrow_ele > 0) {
+ s_ele = sd->arrow_ele;
+ s_ele_ = sd->arrow_ele;
+ }
+ flag=(flag&~BF_RANGEMASK)|BF_LONG;
break;
case AS_SPLASHER: /* ƒxƒiƒ€ƒXƒvƒ‰ƒbƒVƒƒ[ */
damage = damage*(200+20*skill_lv+20*pc_checkskill(sd,AS_POISONREACT))/100;
damage2 = damage2*(200+20*skill_lv+20*pc_checkskill(sd,AS_POISONREACT))/100;
- break;
- case PA_SACRIFICE:
- if(sd){
- int hp, mhp, damage3;
- hp = battle_get_hp(src);
- mhp = battle_get_max_hp(src);
- damage3 = mhp*9/100;
- damage = damage*damage3*(90+10*skill_lv)/10000;
- damage2 = damage2*damage3*(90+10*skill_lv)/10000;
- }
+ no_cardfix = 1;
+ hitrate = 1000000;
break;
case ASC_BREAKER: // -- moonsoul (special damage for ASC_BREAKER skill)
if(sd){
- int damage3;
- int mdef1=battle_get_mdef(target);
- int mdef2=battle_get_mdef2(target);
- int imdef_flag=0;
-
- damage = ((damage * 5) + (skill_lv * battle_get_int(src) * 5) + rand()%500 + 500) /2;
- damage2 = ((damage2 * 5) + (skill_lv * battle_get_int(src) * 5) + rand()%500 + 500) /2;
- damage3 = damage;
- hitrate = 1000000;
-
- if(sd->ignore_mdef_ele & (1<<t_ele) || sd->ignore_mdef_race & (1<<t_race))
+ // calculate physical part of damage
+#ifndef TWILIGHT
+ damage = damage * skill_lv;
+ damage2 = damage2 * skill_lv;
+#else /* TWILIGHT */
+ damage = damage * skill_lv * 0.5; //Halved by Krel
+ damage2 = damage2 * skill_lv * 0.5; //Halved by Krel
+ // element modifier added right after this
+
+ // calculate magic part of damage
+ damage3 = skill_lv * status_get_int(src) * 5 * 0.5; //Krel
+ // ignores magic defense now [Celest]
+ /*if(sd->ignore_mdef_ele & (1<<t_ele) || sd->ignore_mdef_race & (1<<t_race))
imdef_flag = 1;
if(t_mode & 0x20) {
if(sd->ignore_mdef_race & (1<<10))
@@ -3487,14 +2334,23 @@ static struct Damage battle_calc_pc_weapon_attack(
damage3 = (damage3*(100-mdef1))/100 - mdef2;
}
}
-
+
if(damage3<1)
damage3=1;
- damage3=battle_attr_fix(damage2,s_ele_, battle_get_element(target) );
+ damage3=battle_attr_fix(damage2,s_ele_, status_get_element(target) );*/
+
+#endif /* TWILIGHT */
+ flag=(flag&~BF_RANGEMASK)|BF_LONG;
}
break;
}
+ if (div_flag && div_ > 1) { // [Skotlex]
+ damage *= div_;
+ damage2 *= div_;
+ }
+ if (sd && skill_num > 0 && sd->skillatk[0] == skill_num)
+ damage += damage*sd->skillatk[1]/100;
}
if(da == 2) { //ŽO’i¶‚ª”­“®‚µ‚Ä‚¢‚é‚©
type = 0x08;
@@ -3505,20 +2361,20 @@ static struct Damage battle_calc_pc_weapon_attack(
if( skill_num!=NPC_CRITICALSLASH ){
// ‘Î Û‚Ì–hŒä—͂ɂæ‚éƒ_ƒ[ƒW‚ÌŒ¸­
// ƒfƒBƒoƒCƒ“ƒvƒƒeƒNƒVƒ‡ƒ“i‚±‚±‚Å‚¢‚¢‚Ì‚©‚ÈHj
- if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && def1 < 1000000) { //DEF, VIT–³Ž‹
+ if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && skill_num != AM_ACIDTERROR && def1 < 1000000) { //DEF, VIT–³Ž‹
int t_def;
- target_count = 1 + battle_counttargeted(target,src,battle_config.vit_penaly_count_lv);
- if(battle_config.vit_penaly_type > 0) {
- if(target_count >= battle_config.vit_penaly_count) {
- if(battle_config.vit_penaly_type == 1) {
- def1 = (def1 * (100 - (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num))/100;
- def2 = (def2 * (100 - (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num))/100;
- t_vit = (t_vit * (100 - (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num))/100;
+ target_count = 1 + battle_counttargeted(target,src,battle_config.vit_penalty_count_lv);
+ if(battle_config.vit_penalty_type > 0) {
+ if(target_count >= battle_config.vit_penalty_count) {
+ if(battle_config.vit_penalty_type == 1) {
+ def1 = (def1 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100;
+ def2 = (def2 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100;
+ t_vit = (t_vit * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100;
}
- else if(battle_config.vit_penaly_type == 2) {
- def1 -= (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num;
- def2 -= (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num;
- t_vit -= (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num;
+ else if(battle_config.vit_penalty_type == 2) {
+ def1 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num;
+ def2 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num;
+ t_vit -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num;
}
if(def1 < 0) def1 = 0;
if(def2 < 1) def2 = 1;
@@ -3527,6 +2383,19 @@ static struct Damage battle_calc_pc_weapon_attack(
}
t_def = def2*8/10;
vitbonusmax = (t_vit/20)*(t_vit/20)-1;
+ if (tmd) {
+ if(t_mode & 0x20) {
+ if(sd->ignore_def_mob & 2)
+ idef_flag = 1;
+ if(sd->ignore_def_mob_ & 2)
+ idef_flag_ = 1;
+ } else {
+ if(sd->ignore_def_mob & 1)
+ idef_flag = 1;
+ if(sd->ignore_def_mob_ & 1)
+ idef_flag_ = 1;
+ }
+ }
if(sd->ignore_def_ele & (1<<t_ele) || sd->ignore_def_race & (1<<t_race))
idef_flag = 1;
if(sd->ignore_def_ele_ & (1<<t_ele) || sd->ignore_def_race_ & (1<<t_race))
@@ -3567,24 +2436,39 @@ static struct Damage battle_calc_pc_weapon_attack(
// ó‘ÔˆÙí’†‚̃_ƒ[ƒW’ljÁ‚ŃNƒŠƒeƒBƒJƒ‹‚É‚à—LŒø‚ȃXƒLƒ‹
if (sc_data) {
// ƒGƒ“ƒ`ƒƒƒ“ƒgƒfƒbƒhƒŠ[ƒ|ƒCƒYƒ“
- if(sc_data[SC_EDP].timer != -1) {
+ if(!no_cardfix && sc_data[SC_EDP].timer != -1 && skill_num != ASC_BREAKER && skill_num != ASC_METEORASSAULT) {
damage += damage * (150 + sc_data[SC_EDP].val1 * 50) / 100;
- damage2 += damage2 * (150 + sc_data[SC_EDP].val1 * 50) / 100;
no_cardfix = 1;
}
+ // sacrifice works on boss monsters, and does 9% damage to self [Celest]
+ if (!skill_num && /*!(t_mode&0x20) &&*/ sc_data[SC_SACRIFICE].timer != -1) {
+ int mhp = status_get_max_hp(src);
+ int dmg = mhp * 9/100;
+ pc_heal(sd, -dmg, 0);
+ damage = dmg * (90 + sc_data[SC_SACRIFICE].val1 * 10) / 100;
+ damage2 = 0;
+ hitrate = 1000000;
+ s_ele = 0;
+ s_ele_ = 0;
+ skill_num = PA_SACRIFICE;
+ //clif_skill_nodamage(src,target,skill_num,skill_lv,1); // this doesn't show effect either.. hmm =/
+ sc_data[SC_SACRIFICE].val2 --;
+ if (sc_data[SC_SACRIFICE].val2 == 0)
+ status_change_end(src, SC_SACRIFICE,-1);
+ }
}
// ¸˜Bƒ_ƒ[ƒW‚̒ljÁ
if( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST) { //DEF, VIT–³Ž‹
- damage += battle_get_atk2(src);
- damage2 += battle_get_atk_2(src);
+ damage += status_get_atk2(src);
+ damage2 += status_get_atk_2(src);
}
if(skill_num == CR_SHIELDBOOMERANG) {
if(sd->equip_index[8] >= 0) {
int index = sd->equip_index[8];
if(sd->inventory_data[index] && sd->inventory_data[index]->type == 5) {
damage += sd->inventory_data[index]->weight/10;
- damage += sd->status.inventory[index].refine * pc_getrefinebonus(0,1);
+ damage += sd->status.inventory[index].refine * status_getrefinebonus(0,1);
}
}
}
@@ -3593,7 +2477,7 @@ static struct Damage battle_calc_pc_weapon_attack(
int index = sd->equip_index[9];
if(sd->inventory_data[index] && sd->inventory_data[index]->type == 4) {
damage += (int)(double)(sd->inventory_data[index]->weight*(0.8*skill_lv*4/10));
- damage += sd->status.inventory[index].refine * pc_getrefinebonus(0,1);
+ damage += sd->status.inventory[index].refine * status_getrefinebonus(0,1);
}
}
}
@@ -3617,10 +2501,10 @@ static struct Damage battle_calc_pc_weapon_attack(
// ‰ñ”ðC³
if( hitrate < 1000000 && t_sc_data ) { // •K’†UŒ‚
if(t_sc_data[SC_FOGWALL].timer != -1 && flag&BF_LONG)
- hitrate -= 50;
+ hitrate -= 75;
if (t_sc_data[SC_SLEEP].timer!=-1 || // ‡–°‚Í•K’†
t_sc_data[SC_STAN].timer!=-1 || // ƒXƒ^ƒ“‚Í•K’†
- t_sc_data[SC_FREEZE].timer!=-1 ||
+ t_sc_data[SC_FREEZE].timer!=-1 ||
(t_sc_data[SC_STONE].timer!=-1 && t_sc_data[SC_STONE].val2==0)) // “€Œ‹‚Í•K’†
hitrate = 1000000;
}
@@ -3653,17 +2537,20 @@ static struct Damage battle_calc_pc_weapon_attack(
cardfix=cardfix*(100+sd->addrace[t_race])/100; // Ží‘°‚É‚æ‚éƒ_ƒ[ƒWC³
cardfix=cardfix*(100+sd->addele[t_ele])/100; // ‘®«‚É‚æ‚éƒ_ƒ[ƒWC³
cardfix=cardfix*(100+sd->addsize[t_size])/100; // ƒTƒCƒY‚É‚æ‚éƒ_ƒ[ƒWC³
+ cardfix=cardfix*(100+sd->addrace2[t_race2])/100;
}
else {
cardfix=cardfix*(100+sd->addrace[t_race]+sd->addrace_[t_race])/100; // Ží‘°‚É‚æ‚éƒ_ƒ[ƒWC³(¶Žè‚É‚æ‚é’ljÁ‚ ‚è)
cardfix=cardfix*(100+sd->addele[t_ele]+sd->addele_[t_ele])/100; // ‘®«‚É‚æ‚éƒ_ƒ[ƒWC³(¶Žè‚É‚æ‚é’ljÁ‚ ‚è)
cardfix=cardfix*(100+sd->addsize[t_size]+sd->addsize_[t_size])/100; // ƒTƒCƒY‚É‚æ‚éƒ_ƒ[ƒWC³(¶Žè‚É‚æ‚é’ljÁ‚ ‚è)
+ cardfix=cardfix*(100+sd->addrace2[t_race2]+sd->addrace2_[t_race2])/100;
}
}
else { //‹|–î
cardfix=cardfix*(100+sd->addrace[t_race]+sd->arrow_addrace[t_race])/100; // Ží‘°‚É‚æ‚éƒ_ƒ[ƒWC³(‹|–î‚É‚æ‚é’ljÁ‚ ‚è)
cardfix=cardfix*(100+sd->addele[t_ele]+sd->arrow_addele[t_ele])/100; // ‘®«‚É‚æ‚éƒ_ƒ[ƒWC³(‹|–î‚É‚æ‚é’ljÁ‚ ‚è)
cardfix=cardfix*(100+sd->addsize[t_size]+sd->arrow_addsize[t_size])/100; // ƒTƒCƒY‚É‚æ‚éƒ_ƒ[ƒWC³(‹|–î‚É‚æ‚é’ljÁ‚ ‚è)
+ cardfix=cardfix*(100+sd->addrace2[t_race2])/100;
}
if(t_mode & 0x20) { //ƒ{ƒX
if(!sd->state.arrow_atk) { //‹|–îUŒ‚ˆÈŠO‚È‚ç
@@ -3686,7 +2573,7 @@ static struct Damage battle_calc_pc_weapon_attack(
cardfix=cardfix*(100+sd->addrace[11]+sd->arrow_addrace[11])/100; //ƒ{ƒXˆÈŠOƒ‚ƒ“ƒXƒ^[‚ɒljÁƒ_ƒ[ƒW(‹|–î‚É‚æ‚é’ljÁ‚ ‚è)
}
//“Á’èClass—p•Ⳉ—(­—‚Ì“ú‹L¨ƒ{ƒ“ƒSƒ“—pH)
- t_class = battle_get_class(target);
+ t_class = status_get_class(target);
for(i=0;i<sd->add_damage_class_count;i++) {
if(sd->add_damage_classid[i] == t_class) {
cardfix=cardfix*(100+sd->add_damage_classrate[i])/100;
@@ -3703,6 +2590,7 @@ static struct Damage battle_calc_pc_weapon_attack(
cardfix=cardfix*(100+sd->addrace_[t_race])/100; // Ží‘°‚É‚æ‚éƒ_ƒ[ƒWC³¶Žè
cardfix=cardfix*(100+sd->addele_[t_ele])/100; // ‘® «‚É‚æ‚éƒ_ƒ[ƒWC³¶Žè
cardfix=cardfix*(100+sd->addsize_[t_size])/100; // ƒTƒCƒY‚É‚æ‚éƒ_ƒ[ƒWC³¶Žè
+ cardfix=cardfix*(100+sd->addrace2_[t_race2])/100;
if(t_mode & 0x20) //ƒ{ƒX
cardfix=cardfix*(100+sd->addrace_[10])/100; //ƒ{ƒXƒ‚ƒ“ƒXƒ^[‚ɒljÁƒ_ƒ[ƒW¶Žè
else
@@ -3716,27 +2604,24 @@ static struct Damage battle_calc_pc_weapon_attack(
}
}
if(!no_cardfix)
-
damage2=damage2*cardfix/100;
+
//ƒJ[ƒh•Ⳃɂæ‚é¶Žèƒ_ƒ[ƒW‘‰Á
//ƒJ[ƒh‚É‚æ‚éƒ_ƒ[ƒW‘‰Áˆ—(¶Žè)‚±‚±‚Ü‚Å
-// -- moonsoul (cardfix for magic damage portion of ASC_BREAKER)
- if(skill_num == ASC_BREAKER)
- damage3 = damage3 * cardfix / 100;
-
//ƒJ[ƒh‚É‚æ‚éƒ_ƒ[ƒWŒ¸Šˆ—‚±‚±‚©‚ç
if(tsd){ //‘ÎÛ‚ªPC‚Ìê‡
cardfix=100;
cardfix=cardfix*(100-tsd->subrace[s_race])/100; // Ží‘°‚É‚æ‚éƒ_ƒ[ƒW‘Ï«
cardfix=cardfix*(100-tsd->subele[s_ele])/100; // ‘®«‚É‚æ‚éƒ_ƒ[ƒW‘Ï«
- if(battle_get_mode(src) & 0x20)
+ cardfix=cardfix*(100-tsd->subsize[s_size])/100;
+ if(status_get_mode(src) & 0x20)
cardfix=cardfix*(100-tsd->subrace[10])/100; //ƒ{ƒX‚©‚ç‚ÌUŒ‚‚̓_ƒ[ƒWŒ¸­
else
cardfix=cardfix*(100-tsd->subrace[11])/100; //ƒ{ƒXˆÈŠO‚©‚ç‚ÌUŒ‚‚̓_ƒ[ƒWŒ¸­
//“Á’èClass—p•Ⳉ—¶Žè(­—‚Ì“ú‹L¨ƒ{ƒ“ƒSƒ“—pH)
for(i=0;i<tsd->add_def_class_count;i++) {
- if(tsd->add_def_classid[i] == sd->status.class) {
+ if(tsd->add_def_classid[i] == sd->status.class_) {
cardfix=cardfix*(100-tsd->add_def_classrate[i])/100;
break;
}
@@ -3756,29 +2641,29 @@ static struct Damage battle_calc_pc_weapon_attack(
if(t_sc_data[SC_DEFENDER].timer != -1 && flag&BF_LONG) //ƒfƒBƒtƒFƒ“ƒ_[ó‘Ԃʼn“‹——£UŒ‚
cardfix=cardfix*(100-t_sc_data[SC_DEFENDER].val2)/100; //ƒfƒBƒtƒFƒ“ƒ_[‚É‚æ‚錸Š
if(t_sc_data[SC_FOGWALL].timer != -1 && flag&BF_LONG)
- cardfix=cardfix*(100-t_sc_data[SC_FOGWALL].val2)/100;
+ cardfix=cardfix*50/100;
if(cardfix != 100) {
damage=damage*cardfix/100; //ƒfƒBƒtƒFƒ“ƒ_[•Ⳃɂæ‚éƒ_ƒ[ƒWŒ¸­
damage2=damage2*cardfix/100; //ƒfƒBƒtƒFƒ“ƒ_[•Ⳃɂæ‚é¶Žèƒ_ƒ[ƒWŒ¸­
}
if(t_sc_data[SC_ASSUMPTIO].timer != -1){ //ƒAƒXƒ€ƒvƒeƒBƒI
if(!map[target->m].flag.pvp){
- damage=damage/3;
- damage2=damage2/3;
- }else{
- damage=damage/2;
- damage2=damage2/2;
+ damage=damage/3;
+ damage2=damage2/3;
+ }else{
+ damage=damage/2;
+ damage2=damage2/2;
+ }
}
}
- }
//‘ÎۂɃXƒe[ƒ^ƒXˆÙ킪‚ ‚éꇂ̃_ƒ[ƒWŒ¸ŽZˆ—‚±‚±‚Ü‚Å
if(damage < 0) damage = 0;
if(damage2 < 0) damage2 = 0;
// ‘® «‚Ì“K—p
- damage=battle_attr_fix(damage,s_ele, battle_get_element(target) );
- damage2=battle_attr_fix(damage2,s_ele_, battle_get_element(target) );
+ damage=battle_attr_fix(damage,s_ele, status_get_element(target) );
+ damage2=battle_attr_fix(damage2,s_ele_, status_get_element(target) );
// ¯‚Ì‚©‚¯‚çA‹C‹…‚Ì“K—p
damage += sd->star;
@@ -3797,16 +2682,16 @@ static struct Damage battle_calc_pc_weapon_attack(
// >“ñ“—¬‚̶‰Eƒ_ƒ[ƒWŒvŽZ’N‚©‚â‚Á‚Ä‚­‚ê‚¥‚¥‚¥‚¥‚¦‚¦‚¦I
// >map_session_data ‚ɶŽèƒ_ƒ[ƒW(atk,atk2)’ljÁ‚µ‚Ä
- // >pc_calcstatus()‚Å‚â‚é‚ׂ«‚©‚ÈH
+ // >status_calc_pc()‚Å‚â‚é‚ׂ«‚©‚ÈH
// map_session_data ‚ɶŽè•Ší(atk,atk2,ele,star,atkmods)’ljÁ‚µ‚Ä
- // pc_calcstatus()‚Ńf[ƒ^‚ð“ü—Í‚µ‚Ä‚¢‚Ü‚·
+ // status_calc_pc()‚Ńf[ƒ^‚ð“ü—Í‚µ‚Ä‚¢‚Ü‚·
//¶Žè‚̂ݕŠí‘•”õ
if(sd->weapontype1 == 0 && sd->weapontype2 > 0) {
damage = damage2;
damage2 = 0;
}
-
+
// ‰EŽèA¶ŽèC—û‚Ì“K—p
if(sd->status.weapon > 16) {// “ñ“—¬‚©?
int dmg = damage, dmg2 = damage2;
@@ -3838,14 +2723,14 @@ static struct Damage battle_calc_pc_weapon_attack(
// ƒCƒ“ƒxƒiƒ€C³
if(skill_num==TF_POISON){
- damage = battle_attr_fix(damage + 15*skill_lv, s_ele, battle_get_element(target) );
+ damage = battle_attr_fix(damage + 15*skill_lv, s_ele, status_get_element(target) );
}
if(skill_num==MC_CARTREVOLUTION){
- damage = battle_attr_fix(damage, 0, battle_get_element(target) );
+ damage = battle_attr_fix(damage, 0, status_get_element(target) );
}
// Š®‘S‰ñ”ð‚Ì”»’è
- if(skill_num == 0 && skill_lv >= 0 && tsd!=NULL && div_ < 255 && rand()%1000 < battle_get_flee2(target) ){
+ if(skill_num == 0 && tsd!=NULL && div_ < 255 && rand()%1000 < status_get_flee2(target) ){
damage=damage2=0;
type=0x0b;
dmg_lv = ATK_LUCKY;
@@ -3853,7 +2738,7 @@ static struct Damage battle_calc_pc_weapon_attack(
// ‘ÎÛ‚ªŠ®‘S‰ñ”ð‚ð‚·‚éݒ肪ON‚È‚ç
if(battle_config.enemy_perfect_flee) {
- if(skill_num == 0 && skill_lv >= 0 && tmd!=NULL && div_ < 255 && rand()%1000 < battle_get_flee2(target) ) {
+ if(skill_num == 0 && tmd!=NULL && div_ < 255 && rand()%1000 < status_get_flee2(target) ) {
damage=damage2=0;
type=0x0b;
dmg_lv = ATK_LUCKY;
@@ -3921,21 +2806,14 @@ static struct Damage battle_calc_pc_weapon_attack(
}
}
-
-// -- moonsoul (final combination of phys, mag damage for ASC_BREAKER)
- if(skill_num == ASC_BREAKER) {
- damage += damage3;
- damage2 += damage3;
- }
-
wd.damage=damage;
wd.damage2=damage2;
wd.type=type;
wd.div_=div_;
- wd.amotion=battle_get_amotion(src);
+ wd.amotion=status_get_amotion(src);
if(skill_num == KN_AUTOCOUNTER)
wd.amotion >>= 1;
- wd.dmotion=battle_get_dmotion(target);
+ wd.dmotion=status_get_dmotion(target);
wd.blewcount=blewcount;
wd.flag=flag;
wd.dmg_lv=dmg_lv;
@@ -3972,32 +2850,45 @@ struct Damage battle_calc_weapon_attack(
memset(&wd,0,sizeof(wd));
if(battle_config.equipment_breaking && src->type==BL_PC && (wd.damage > 0 || wd.damage2 > 0)) {
- struct map_session_data *sd=(struct map_session_data *)src;
- int breakrate=1;
- if(sd->status.weapon && sd->status.weapon!=11) {
- if(target->type == BL_PC && sd->sc_data[SC_MELTDOWN].timer!=-1){
- breakrate+=100*sd->sc_data[SC_MELTDOWN].val1;
- if(rand()%10000 < breakrate*battle_config.equipment_break_rate/100 || breakrate >= 10000)
- pc_breakweapon((struct map_session_data *)target);
+ struct map_session_data *sd = (struct map_session_data *)src;
+ // weapon = 0, armor = 1
+ int breakrate = 1; //0.01% default self weapon breaking chance [DracoRPG]
+ int breakrate_[2] = {0,0}; //enemy breaking chance [celest]
+ int breaktime = 5000;
+
+ breakrate_[0] += sd->break_weapon_rate;
+ breakrate_[1] += sd->break_armor_rate;
+
+ if (sd->sc_count) {
+ if (sd->sc_data[SC_MELTDOWN].timer!=-1) {
+ breakrate_[0] += 100*sd->sc_data[SC_MELTDOWN].val1;
+ breakrate_[1] = 70*sd->sc_data[SC_MELTDOWN].val1;
+ breaktime = skill_get_time2(WS_MELTDOWN,1);
}
if(sd->sc_data[SC_OVERTHRUST].timer!=-1)
- breakrate+=20*sd->sc_data[SC_OVERTHRUST].val1;
- if(wd.type==0x0a)
- breakrate*=2;
- if(rand()%10000 < breakrate*battle_config.equipment_break_rate/100 || breakrate >= 10000) {
- if(pc_breakweapon(sd)==1)
+ breakrate += 10;
+ }
+
+ if(sd->status.weapon && sd->status.weapon != 11) {
+ if(rand() % 10000 < breakrate * battle_config.equipment_break_rate / 100 || breakrate >= 10000)
+ if (pc_breakweapon(sd) == 1)
wd = battle_calc_pc_weapon_attack(src,target,skill_num,skill_lv,wflag);
- }
}
- }
-
- if (battle_config.equipment_breaking && target->type == BL_PC && (wd.damage > 0 || wd.damage2 > 0)) {
- int breakrate=1;
- if(src->type==BL_PC && ((struct map_session_data *)src)->sc_data[SC_MELTDOWN].timer!=-1) breakrate+=70*((struct map_session_data *)src)->sc_data[SC_MELTDOWN].val1;
- if (wd.type==0x0a)
- breakrate*=2;
- if (rand()%10000 < breakrate*battle_config.equipment_break_rate/100 || breakrate >= 10000) {
- pc_breakarmor((struct map_session_data *)target);
+ if(rand() % 10000 < breakrate_[0] * battle_config.equipment_break_rate / 100 || breakrate_[0] >= 10000) {
+ if (target->type == BL_PC) {
+ struct map_session_data *tsd = (struct map_session_data *)target;
+ if(tsd->status.weapon != 11)
+ pc_breakweapon(tsd);
+ } else
+ status_change_start(target,SC_STRIPWEAPON,1,75,0,0,breaktime,0);
+ }
+ if(rand() % 10000 < breakrate_[1] * battle_config.equipment_break_rate/100 || breakrate_[1] >= 10000) {
+ if (target->type == BL_PC) {
+ struct map_session_data *tsd = (struct map_session_data *)target;
+ if(tsd->status.weapon != 11)
+ pc_breakarmor(tsd);
+ } else
+ status_change_start(target,SC_STRIPSHIELD,1,75,0,0,breaktime,0);
}
}
@@ -4011,13 +2902,14 @@ struct Damage battle_calc_weapon_attack(
struct Damage battle_calc_magic_attack(
struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int flag)
{
- int mdef1=battle_get_mdef(target);
- int mdef2=battle_get_mdef2(target);
+ int mdef1=status_get_mdef(target);
+ int mdef2=status_get_mdef2(target);
int matk1,matk2,damage=0,div_=1,blewcount=skill_get_blewcount(skill_num,skill_lv),rdamage = 0;
struct Damage md;
int aflag;
int normalmagic_flag=1;
- int ele=0,race=7,t_ele=0,t_race=7,t_mode = 0,cardfix,t_class,i;
+ int matk_flag = 1;
+ int ele=0,race=7,size=1,race2=7,t_ele=0,t_race=7,t_mode = 0,cardfix,t_class,i;
struct map_session_data *sd=NULL,*tsd=NULL;
struct mob_data *tmd = NULL;
@@ -4034,13 +2926,15 @@ struct Damage battle_calc_magic_attack(
return md;
}
- matk1=battle_get_matk1(bl);
- matk2=battle_get_matk2(bl);
+ matk1=status_get_matk1(bl);
+ matk2=status_get_matk2(bl);
ele = skill_get_pl(skill_num);
- race = battle_get_race(bl);
- t_ele = battle_get_elem_type(target);
- t_race = battle_get_race(target);
- t_mode = battle_get_mode(target);
+ race = status_get_race(bl);
+ size = status_get_size(bl);
+ race2 = status_get_race2(bl);
+ t_ele = status_get_elem_type(target);
+ t_race = status_get_race(target);
+ t_mode = status_get_mode(target);
#define MATK_FIX( a,b ) { matk1=matk1*(a)/(b); matk2=matk2*(a)/(b); }
@@ -4078,10 +2972,10 @@ struct Damage battle_calc_magic_attack(
case PR_TURNUNDEAD: // UŒ‚ƒŠƒUƒŒƒNƒVƒ‡ƒ“‚ƃ^[ƒ“ƒAƒ“ƒfƒbƒh
if(target->type != BL_PC && battle_check_undead(t_race,t_ele)){
int hp, mhp, thres;
- hp = battle_get_hp(target);
- mhp = battle_get_max_hp(target);
- thres = (skill_lv * 20) + battle_get_luk(bl)+
- battle_get_int(bl) + battle_get_lv(bl)+
+ hp = status_get_hp(target);
+ mhp = status_get_max_hp(target);
+ thres = (skill_lv * 20) + status_get_luk(bl)+
+ status_get_int(bl) + status_get_lv(bl)+
((200 - hp * 200 / mhp));
if(thres > 700) thres = 700;
// if(battle_config.battle_log)
@@ -4089,7 +2983,7 @@ struct Damage battle_calc_magic_attack(
if(rand()%1000 < thres && !(t_mode&0x20)) // ¬Œ÷
damage = hp;
else // ޏ”s
- damage = battle_get_lv(bl) + battle_get_int(bl) + skill_lv * 10;
+ damage = status_get_lv(bl) + status_get_int(bl) + skill_lv * 10;
}
normalmagic_flag=0;
break;
@@ -4157,7 +3051,7 @@ struct Damage battle_calc_magic_attack(
break;
case WZ_STORMGUST: // ƒXƒg[ƒ€ƒKƒXƒg
MATK_FIX( skill_lv*40+100 ,100 );
- blewcount|=0x10000;
+// blewcount|=0x10000;
break;
case AL_HOLYLIGHT: // ƒz[ƒŠ[ƒ‰ƒCƒg
MATK_FIX( 125,100 );
@@ -4174,15 +3068,30 @@ struct Damage battle_calc_magic_attack(
printf("battle_calc_magic_attack(): napalmvulcan enemy count=0 !\n");
}
break;
+ case PF_SOULBURN: // Celest
+ if (target->type != BL_PC || skill_lv < 5) {
+ memset(&md,0,sizeof(md));
+ return md;
+ } else if (target->type == BL_PC) {
+ damage = ((struct map_session_data *)target)->status.sp * 2;
+ matk_flag = 0; // don't consider matk and matk2
+ }
+ break;
+ case ASC_BREAKER:
+ damage = rand()%500 + 500 + skill_lv * status_get_int(bl) * 5;
+ matk_flag = 0; // don't consider matk and matk2
+ break;
}
}
if(normalmagic_flag){ // ˆê”Ê–‚–@ƒ_ƒ[ƒWŒvŽZ
int imdef_flag=0;
- if(matk1>matk2)
- damage= matk2+rand()%(matk1-matk2+1);
- else
- damage= matk2;
+ if (matk_flag) {
+ if(matk1>matk2)
+ damage= matk2+rand()%(matk1-matk2+1);
+ else
+ damage= matk2;
+ }
if(sd) {
if(sd->ignore_mdef_ele & (1<<t_ele) || sd->ignore_mdef_race & (1<<t_race))
imdef_flag = 1;
@@ -4216,7 +3125,7 @@ struct Damage battle_calc_magic_attack(
cardfix=cardfix*(100+sd->magic_addrace[10])/100;
else
cardfix=cardfix*(100+sd->magic_addrace[11])/100;
- t_class = battle_get_class(target);
+ t_class = status_get_class(target);
for(i=0;i<sd->add_magic_damage_class_count;i++) {
if(sd->add_magic_damage_classid[i] == t_class) {
cardfix=cardfix*(100+sd->add_magic_damage_classrate[i])/100;
@@ -4224,15 +3133,19 @@ struct Damage battle_calc_magic_attack(
}
}
damage=damage*cardfix/100;
+ if (skill_num > 0 && sd->skillatk[0] == skill_num)
+ damage += damage*sd->skillatk[1]/100;
}
if( tsd ){
- int s_class = battle_get_class(bl);
+ int s_class = status_get_class(bl);
cardfix=100;
cardfix=cardfix*(100-tsd->subele[ele])/100; // ‘® «‚É‚æ‚éƒ_ƒ[ƒW‘Ï«
cardfix=cardfix*(100-tsd->subrace[race])/100; // Ží‘°‚É‚æ‚éƒ_ƒ[ƒW‘Ï«
+ cardfix=cardfix*(100-tsd->subsize[size])/100;
cardfix=cardfix*(100-tsd->magic_subrace[race])/100;
- if(battle_get_mode(bl) & 0x20)
+ cardfix=cardfix*(100-tsd->subrace2[race2])/100; // Ží‘°‚É‚æ‚éƒ_ƒ[ƒW‘Ï«
+ if(status_get_mode(bl) & 0x20)
cardfix=cardfix*(100-tsd->magic_subrace[10])/100;
else
cardfix=cardfix*(100-tsd->magic_subrace[11])/100;
@@ -4247,13 +3160,13 @@ struct Damage battle_calc_magic_attack(
}
if(damage < 0) damage = 0;
- damage=battle_attr_fix(damage, ele, battle_get_element(target) ); // ‘® «C³
+ damage=battle_attr_fix(damage, ele, status_get_element(target) ); // ‘® «C³
if(skill_num == CR_GRANDCROSS) { // ƒOƒ‰ƒ“ƒhƒNƒƒX
struct Damage wd;
wd=battle_calc_weapon_attack(bl,target,skill_num,skill_lv,flag);
damage = (damage + wd.damage) * (100 + 40*skill_lv)/100;
- if(battle_config.gx_dupele) damage=battle_attr_fix(damage, ele, battle_get_element(target) ); //‘®«2‰ñ‚©‚©‚é
+ if(battle_config.gx_dupele) damage=battle_attr_fix(damage, ele, status_get_element(target) ); //‘®«2‰ñ‚©‚©‚é
if(bl==target) damage=damage/2; //”½“®‚Í”¼•ª
}
@@ -4287,8 +3200,8 @@ struct Damage battle_calc_magic_attack(
md.damage=damage;
md.div_=div_;
- md.amotion=battle_get_amotion(bl);
- md.dmotion=battle_get_dmotion(target);
+ md.amotion=status_get_amotion(bl);
+ md.dmotion=status_get_dmotion(target);
md.damage2=0;
md.type=0;
md.blewcount=blewcount;
@@ -4304,16 +3217,16 @@ struct Damage battle_calc_magic_attack(
struct Damage battle_calc_misc_attack(
struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int flag)
{
- int int_=battle_get_int(bl);
-// int luk=battle_get_luk(bl);
- int dex=battle_get_dex(bl);
- int skill,ele,race,cardfix;
+ int int_=status_get_int(bl);
+// int luk=status_get_luk(bl);
+ int dex=status_get_dex(bl);
+ int skill,ele,race,size,cardfix,race2;
struct map_session_data *sd=NULL,*tsd=NULL;
int damage=0,div_=1,blewcount=skill_get_blewcount(skill_num,skill_lv);
struct Damage md;
int damagefix=1;
- int aflag=BF_MISC|BF_LONG|BF_SKILL;
+ int aflag=BF_MISC|BF_SHORT|BF_SKILL;
//return‘O‚̈—‚ª‚ ‚é‚Ì‚Åî•ño—Í•”‚̂ݕÏX
if( bl == NULL || target == NULL ){
@@ -4355,11 +3268,13 @@ struct Damage battle_calc_misc_attack(
damage=(dex/10+int_/2+skill*3+40)*2;
if(flag > 1)
damage /= flag;
+ aflag |= (flag&~BF_RANGEMASK)|BF_LONG;
break;
case TF_THROWSTONE: // Î“Š‚°
damage=50;
damagefix=0;
+ aflag |= (flag&~BF_RANGEMASK)|BF_LONG;
break;
case BA_DISSONANCE: // •s‹¦˜a‰¹
@@ -4367,7 +3282,7 @@ struct Damage battle_calc_misc_attack(
break;
case NPC_SELFDESTRUCTION: // Ž©”š
- damage=battle_get_hp(bl)-(bl==target?1:0);
+ damage=status_get_hp(bl)-(bl==target?1:0);
damagefix=0;
break;
@@ -4378,8 +3293,8 @@ struct Damage battle_calc_misc_attack(
case NPC_DARKBREATH:
{
- struct status_change *sc_data = battle_get_sc_data(target);
- int hitrate=battle_get_hit(bl) - battle_get_flee(target) + 80;
+ struct status_change *sc_data = status_get_sc_data(target);
+ int hitrate=status_get_hit(bl) - status_get_flee(target) + 80;
hitrate = ( (hitrate>95)?95: ((hitrate<5)?5:hitrate) );
if(sc_data && (sc_data[SC_SLEEP].timer!=-1 || sc_data[SC_STAN].timer!=-1 ||
sc_data[SC_FREEZE].timer!=-1 || (sc_data[SC_STONE].timer!=-1 && sc_data[SC_STONE].val2==0) ) )
@@ -4391,13 +3306,25 @@ struct Damage battle_calc_misc_attack(
}
break;
case SN_FALCONASSAULT: /* ƒtƒ@ƒ‹ƒRƒ“ƒAƒTƒ‹ƒg */
- skill = pc_checkskill(sd,HT_STEELCROW); // Celest
- damage=((150+50*skill_lv)*(dex/10+int_/2+skill*3+40)*2)/100;
+#ifdef TWILIGHT
+ if( sd==NULL || (skill = pc_checkskill(sd,HT_BLITZBEAT)) <= 0)
+ skill=0;
+ damage=(100+50*skill_lv+(dex/10+int_/2+skill*3+40)*2) * 2;
+#else
+ if( sd==NULL || (skill = pc_checkskill(sd,HT_STEELCROW)) <= 0)
+ skill=0;
+ damage=((150+50*skill_lv)*(dex/10+int_/2+skill*3+40)*2)/100; // [Celest]
+#endif
+ if(flag > 1)
+ damage /= flag;
+ aflag |= (flag&~BF_RANGEMASK)|BF_LONG;
break;
}
ele = skill_get_pl(skill_num);
- race = battle_get_race(bl);
+ race = status_get_race(bl);
+ size = status_get_size(bl);
+ race2 = status_get_race(bl);
if(damagefix){
if(damage<1 && skill_num != NPC_DARKBREATH)
@@ -4407,27 +3334,35 @@ struct Damage battle_calc_misc_attack(
cardfix=100;
cardfix=cardfix*(100-tsd->subele[ele])/100; // ‘®«‚É‚æ‚éƒ_ƒ[ƒW‘Ï«
cardfix=cardfix*(100-tsd->subrace[race])/100; // Ží‘°‚É‚æ‚éƒ_ƒ[ƒW‘Ï«
+ cardfix=cardfix*(100-tsd->subsize[size])/100;
cardfix=cardfix*(100-tsd->misc_def_rate)/100;
+ cardfix=cardfix*(100-tsd->subrace2[race2])/100;
damage=damage*cardfix/100;
}
+ if (sd && skill_num > 0 && sd->skillatk[0] == skill_num)
+ damage += damage*sd->skillatk[1]/100;
+
if(damage < 0) damage = 0;
- damage=battle_attr_fix(damage, ele, battle_get_element(target) ); // ‘®«C³
+ damage=battle_attr_fix(damage, ele, status_get_element(target) ); // ‘®«C³
}
div_=skill_get_num( skill_num,skill_lv );
if(div_>1)
damage*=div_;
- if(damage > 0 && (damage < div_ || (battle_get_def(target) >= 1000000 && battle_get_mdef(target) >= 1000000) ) ) {
+ if(damage > 0 && (damage < div_ || (status_get_def(target) >= 1000000 && status_get_mdef(target) >= 1000000) ) ) {
damage = div_;
}
+ if(status_get_mode(target)&0x40 && damage>0)
+ damage = 1;
+
damage=battle_calc_damage(bl,target,damage,div_,skill_num,skill_lv,aflag); // ÅIC³
md.damage=damage;
md.div_=div_;
- md.amotion=battle_get_amotion(bl);
- md.dmotion=battle_get_dmotion(target);
+ md.amotion=status_get_amotion(bl);
+ md.dmotion=status_get_dmotion(target);
md.damage2=0;
md.type=0;
md.blewcount=blewcount;
@@ -4453,6 +3388,7 @@ struct Damage battle_calc_attack( int attack_type,
default:
if(battle_config.error_log)
printf("battle_calc_attack: unknwon attack type ! %d\n",attack_type);
+ memset(&d,0,sizeof(d));
break;
}
return d;
@@ -4465,7 +3401,7 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
unsigned int tick,int flag)
{
struct map_session_data *sd=NULL;
- struct status_change *sc_data = battle_get_sc_data(src),*t_sc_data=battle_get_sc_data(target);
+ struct status_change *sc_data = status_get_sc_data(src),*t_sc_data=status_get_sc_data(target);
short *opt1;
int race = 7, ele = 0;
int damage,rdamage = 0;
@@ -4484,7 +3420,7 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
if(target->type == BL_PC && pc_isdead((struct map_session_data *)target))
return 0;
- opt1=battle_get_opt1(src);
+ opt1=status_get_opt1(src);
if(opt1 && *opt1 > 0) {
battle_stopattack(src);
return 0;
@@ -4495,11 +3431,11 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
}
if(battle_check_target(src,target,BCT_ENEMY) <= 0 &&
- !battle_check_range(src,target,0))
+ !battle_check_range(src,target,0))
return 0; // UŒ‚‘ÎÛŠO
- race = battle_get_race(target);
- ele = battle_get_elem_type(target);
+ race = status_get_race(target);
+ ele = status_get_elem_type(target);
if(battle_check_target(src,target,BCT_ENEMY) > 0 &&
battle_check_range(src,target,0)){
// UŒ‚‘ÎۂƂȂ肤‚é‚Ì‚ÅUŒ‚
@@ -4549,17 +3485,17 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
}
}
if(rdamage > 0)
- clif_damage(src,src,tick, wd.amotion,0,rdamage,1,4,0);
+ clif_damage(src,src,tick,wd.amotion,wd.dmotion,rdamage,1,4,0);
}
if (wd.div_ == 255 && sd) { //ŽO’i¶
- int delay = 1000 - 4 * battle_get_agi(src) - 2 * battle_get_dex(src);
+ int delay = 1000 - 4 * status_get_agi(src) - 2 * status_get_dex(src);
int skilllv;
- if(wd.damage+wd.damage2 < battle_get_hp(target)) {
+ if(wd.damage+wd.damage2 < status_get_hp(target)) {
if((skilllv = pc_checkskill(sd, MO_CHAINCOMBO)) > 0)
delay += 300 * battle_config.combo_delay_rate /100; //’ljÁƒfƒBƒŒƒC‚ðconf‚É‚æ‚è’²®
- skill_status_change_start(src,SC_COMBO,MO_TRIPLEATTACK,skilllv,0,0,delay,0);
+ status_change_start(src,SC_COMBO,MO_TRIPLEATTACK,skilllv,0,0,delay,0);
}
sd->attackabletime = sd->canmove_tick = tick + delay;
clif_combo_delay(src,delay);
@@ -4576,23 +3512,23 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
if(sd && sd->splash_range > 0 && (wd.damage > 0 || wd.damage2 > 0) )
skill_castend_damage_id(src,target,0,-1,tick,0);
map_freeblock_lock();
- battle_damage(src,target,(wd.damage+wd.damage2),0);
+ battle_delay_damage(tick+wd.amotion,src,target,(wd.damage+wd.damage2),0);
if(target->prev != NULL &&
(target->type != BL_PC || (target->type == BL_PC && !pc_isdead((struct map_session_data *)target) ) ) ) {
if(wd.damage > 0 || wd.damage2 > 0) {
skill_additional_effect(src,target,0,0,BF_WEAPON,tick);
if(sd) {
if(sd->weapon_coma_ele[ele] > 0 && rand()%10000 < sd->weapon_coma_ele[ele])
- battle_damage(src,target,battle_get_max_hp(target),1);
+ battle_damage(src,target,status_get_max_hp(target),1);
if(sd->weapon_coma_race[race] > 0 && rand()%10000 < sd->weapon_coma_race[race])
- battle_damage(src,target,battle_get_max_hp(target),1);
- if(battle_get_mode(target) & 0x20) {
+ battle_damage(src,target,status_get_max_hp(target),1);
+ if(status_get_mode(target) & 0x20) {
if(sd->weapon_coma_race[10] > 0 && rand()%10000 < sd->weapon_coma_race[10])
- battle_damage(src,target,battle_get_max_hp(target),1);
+ battle_damage(src,target,status_get_max_hp(target),1);
}
else {
if(sd->weapon_coma_race[11] > 0 && rand()%10000 < sd->weapon_coma_race[11])
- battle_damage(src,target,battle_get_max_hp(target),1);
+ battle_damage(src,target,status_get_max_hp(target),1);
}
}
}
@@ -4643,69 +3579,96 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
}
}
if(sd) {
- if(sd->autospell_id > 0 && sd->autospell_lv > 0 && rand()%100 < sd->autospell_rate) {
- int skilllv=sd->autospell_lv,i,f=0,sp;
+ if(sd->autospell_id > 0 && rand()%100 < sd->autospell_rate) {
+ int skilllv = sd->autospell_lv, i;
i = rand()%100;
if(i >= 50) skilllv -= 2;
else if(i >= 15) skilllv--;
if(skilllv < 1) skilllv = 1;
- sp = skill_get_sp(sd->autospell_id,skilllv)*2/3;
- if(sd->status.sp >= sp) {
- if((i=skill_get_inf(sd->autospell_id) == 2) || i == 32)
- f = skill_castend_pos2(src,target->x,target->y,sd->autospell_id,skilllv,tick,flag);
- else {
- switch( skill_get_nk(sd->autospell_id) ) {
- case 0: case 2:
- f = skill_castend_damage_id(src,target,sd->autospell_id,skilllv,tick,flag);
- break;
- case 1:/* Žx‰‡Œn */
- if((sd->autospell_id==AL_HEAL || (sd->autospell_id==ALL_RESURRECTION && target->type != BL_PC)) && battle_check_undead(race,ele))
- f = skill_castend_damage_id(src,target,sd->autospell_id,skilllv,tick,flag);
- else
- f = skill_castend_nodamage_id(src,target,sd->autospell_id,skilllv,tick,flag);
- break;
- }
+
+ if((i=skill_get_inf(sd->autospell_id) == 2) || i == 32)
+ skill_castend_pos2(src,target->x,target->y,sd->autospell_id,skilllv,tick,flag);
+ else {
+ switch( skill_get_nk(sd->autospell_id) ) {
+ case 0: case 2:
+ skill_castend_damage_id(src,target,sd->autospell_id,skilllv,tick,flag);
+ break;
+ case 1:/* Žx‰‡Œn */
+ if((sd->autospell_id==AL_HEAL || (sd->autospell_id==ALL_RESURRECTION && target->type != BL_PC)) && battle_check_undead(race,ele))
+ skill_castend_damage_id(src,target,sd->autospell_id,skilllv,tick,flag);
+ else
+ skill_castend_nodamage_id(src,target,sd->autospell_id,skilllv,tick,flag);
+ break;
}
- if(!f) pc_heal(sd,0,-sp);
- }
+ }
}
- if(wd.flag&BF_WEAPON && src != target && (wd.damage > 0 || wd.damage2 > 0)) {
+ if (wd.flag&BF_WEAPON && src != target && (wd.damage > 0 || wd.damage2 > 0)) {
int hp = 0,sp = 0;
- if(sd->hp_drain_rate && sd->hp_drain_per > 0 && wd.damage > 0 && rand()%100 < sd->hp_drain_rate) {
- hp += (wd.damage * sd->hp_drain_per)/100;
- if(sd->hp_drain_rate > 0 && hp < 1) hp = 1;
- else if(sd->hp_drain_rate < 0 && hp > -1) hp = -1;
- }
- if(sd->hp_drain_rate_ && sd->hp_drain_per_ > 0 && wd.damage2 > 0 && rand()%100 < sd->hp_drain_rate_) {
- hp += (wd.damage2 * sd->hp_drain_per_)/100;
- if(sd->hp_drain_rate_ > 0 && hp < 1) hp = 1;
- else if(sd->hp_drain_rate_ < 0 && hp > -1) hp = -1;
- }
- if(sd->sp_drain_rate && sd->sp_drain_per > 0 && wd.damage > 0 && rand()%100 < sd->sp_drain_rate) {
- sp += (wd.damage * sd->sp_drain_per)/100;
- if(sd->sp_drain_rate > 0 && sp < 1) sp = 1;
- else if(sd->sp_drain_rate < 0 && sp > -1) sp = -1;
+ if (!battle_config.left_cardfix_to_right) { // “ñ“—¬¶ŽèƒJ[ƒh‚Ì‹zŽûŒnŒø‰Ê‚ð‰EŽè‚ɒljÁ‚µ‚È‚¢ê‡
+ hp += battle_calc_drain(wd.damage, sd->hp_drain_rate, sd->hp_drain_per, sd->hp_drain_value);
+ hp += battle_calc_drain(wd.damage2, sd->hp_drain_rate_, sd->hp_drain_per_, sd->hp_drain_value_);
+ sp += battle_calc_drain(wd.damage, sd->sp_drain_rate, sd->sp_drain_per, sd->sp_drain_value);
+ sp += battle_calc_drain(wd.damage2, sd->sp_drain_rate_, sd->sp_drain_per_, sd->sp_drain_value_);
+ } else { // “ñ“—¬¶ŽèƒJ[ƒh‚Ì‹zŽûŒnŒø‰Ê‚ð‰EŽè‚ɒljÁ‚·‚éê‡
+ int hp_drain_rate = sd->hp_drain_rate + sd->hp_drain_rate_;
+ int hp_drain_per = sd->hp_drain_per + sd->hp_drain_per_;
+ int hp_drain_value = sd->hp_drain_value + sd->hp_drain_value_;
+ int sp_drain_rate = sd->sp_drain_rate + sd->sp_drain_rate_;
+ int sp_drain_per = sd->sp_drain_per + sd->sp_drain_per_;
+ int sp_drain_value = sd->sp_drain_value + sd->sp_drain_value_;
+ hp += battle_calc_drain(wd.damage, hp_drain_rate, hp_drain_per, hp_drain_value);
+ sp += battle_calc_drain(wd.damage, sp_drain_rate, sp_drain_per, sp_drain_value);
}
- if(sd->sp_drain_rate_ && sd->sp_drain_per_ > 0 && wd.damage2 > 0 && rand()%100 < sd->sp_drain_rate_) {
- sp += (wd.damage2 * sd->sp_drain_per_)/100;
- if(sd->sp_drain_rate_ > 0 && sp < 1) sp = 1;
- else if(sd->sp_drain_rate_ < 0 && sp > -1) sp = -1;
- }
- if(hp || sp) pc_heal(sd,hp,sp);
+
+ if (hp || sp) pc_heal(sd, hp, sp);
+ if (sd->sp_drain_type && target->type == BL_PC)
+ battle_heal(NULL,target,0,-sp,0);
+ }
+ }
+ if (target->type == BL_PC) {
+ struct map_session_data *tsd = (struct map_session_data *)target;
+ if(tsd && ((sd && !sd->state.arrow_atk) || (status_get_range(src)<=2)) &&
+ tsd->autospell2_id > 0 && rand()%100 < tsd->autospell2_rate) {
+ struct block_list *tbl;
+ int skilllv = tsd->autospell_lv, i;
+ i = rand()%100;
+ if(i >= 50) skilllv -= 2;
+ else if(i >= 15) skilllv--;
+ if(skilllv < 1) skilllv = 1;
+
+ if (tsd->autospell2_type == 0) tbl = target;
+ else tbl = src;
+ if((i=skill_get_inf(tsd->autospell2_id) == 2) || i == 32)
+ skill_castend_pos2(target,tbl->x,tbl->y,tsd->autospell2_id,skilllv,tick,flag);
+ else {
+ switch( skill_get_nk(tsd->autospell2_id) ) {
+ case 0: case 2:
+ skill_castend_damage_id(target,tbl,tsd->autospell2_id,skilllv,tick,flag);
+ break;
+ case 1:/* Žx‰‡Œn */
+ if((tsd->autospell2_id==AL_HEAL || (tsd->autospell2_id==ALL_RESURRECTION && tbl->type != BL_PC)) &&
+ battle_check_undead(status_get_race(tbl),status_get_elem_type(tbl)))
+ skill_castend_damage_id(target,tbl,tsd->autospell2_id,skilllv,tick,flag);
+ else
+ skill_castend_nodamage_id(target,tbl,tsd->autospell2_id,skilllv,tick,flag);
+ break;
+ }
+ }
}
}
if(rdamage > 0)
- battle_damage(target,src,rdamage,0);
+ battle_delay_damage(tick+wd.amotion,target,src,rdamage,0);
+
if(t_sc_data && t_sc_data[SC_AUTOCOUNTER].timer != -1 && t_sc_data[SC_AUTOCOUNTER].val4 > 0) {
if(t_sc_data[SC_AUTOCOUNTER].val3 == src->id)
battle_weapon_attack(target,src,tick,0x8000|t_sc_data[SC_AUTOCOUNTER].val1);
- skill_status_change_end(target,SC_AUTOCOUNTER,-1);
+ status_change_end(target,SC_AUTOCOUNTER,-1);
}
if(t_sc_data && t_sc_data[SC_POISONREACT].timer != -1 && t_sc_data[SC_POISONREACT].val4 > 0) { // poison react [Celest]
if(t_sc_data[SC_POISONREACT].val3 == src->id) {
struct map_session_data *tsd = (struct map_session_data *)target;
- if ((src->type == BL_MOB && battle_get_elem_type(src)==5) || (src->type == BL_PC && battle_get_attack_element(src)==5)) {
+ if ((src->type == BL_MOB && status_get_elem_type(src)==5) || (src->type == BL_PC && status_get_attack_element(src)==5)) {
t_sc_data[SC_POISONREACT].val2 = 0;
battle_weapon_attack(target,src,tick,flag|AS_POISONREACT);
} else {
@@ -4713,19 +3676,18 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
--t_sc_data[SC_POISONREACT].val2;
}
if (t_sc_data[SC_POISONREACT].val2<=0)
- skill_status_change_end(target,SC_POISONREACT,-1);
- }
- }
- if(t_sc_data && t_sc_data[SC_BLADESTOP_WAIT].timer != -1){
- if (!(src->type == BL_MOB && mob_db[((struct mob_data *)src)->class].mode&0x20)) {
- int lv = t_sc_data[SC_BLADESTOP_WAIT].val1;
- skill_status_change_end(target,SC_BLADESTOP_WAIT,-1);
- skill_status_change_start(src,SC_BLADESTOP,lv,1,(int)src,(int)target,skill_get_time2(MO_BLADESTOP,lv),0);
- skill_status_change_start(target,SC_BLADESTOP,lv,2,(int)target,(int)src,skill_get_time2(MO_BLADESTOP,lv),0);
+ status_change_end(target,SC_POISONREACT,-1);
}
}
+ if (t_sc_data && t_sc_data[SC_BLADESTOP_WAIT].timer != -1 &&
+ !(status_get_mode(src)&0x20)) { // ƒ{ƒX‚ɂ͖³Œø
+ int lv = t_sc_data[SC_BLADESTOP_WAIT].val1;
+ status_change_end(target,SC_BLADESTOP_WAIT,-1);
+ status_change_start(src,SC_BLADESTOP,lv,1,(int)src,(int)target,skill_get_time2(MO_BLADESTOP,lv),0);
+ status_change_start(target,SC_BLADESTOP,lv,2,(int)target,(int)src,skill_get_time2(MO_BLADESTOP,lv),0);
+ }
if(t_sc_data && t_sc_data[SC_SPLASHER].timer!=-1) //‰£‚Á‚½‚̂őÎۂ̃xƒiƒ€ƒXƒvƒ‰ƒbƒVƒƒ[ó‘Ô‚ð‰ðœ
- skill_status_change_end(target,SC_SPLASHER,-1);
+ status_change_end(target,SC_SPLASHER,-1);
map_freeblock_unlock();
}
@@ -4789,8 +3751,8 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
return -1;
// Celest
- sc_data = battle_get_sc_data(src);
- tsc_data = battle_get_sc_data(target);
+ sc_data = status_get_sc_data(src);
+ tsc_data = status_get_sc_data(target);
if ((sc_data && sc_data[SC_BASILICA].timer != -1) ||
(tsc_data && tsc_data[SC_BASILICA].timer != -1))
return -1;
@@ -4810,15 +3772,22 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
// ƒXƒLƒ‹ƒ†ƒjƒbƒg‚Ìê‡Ae‚ð‹‚ß‚é
if( src->type==BL_SKILL) {
- int inf2 = skill_get_inf2(((struct skill_unit *)src)->group->skill_id);
- if( (ss=map_id2bl( ((struct skill_unit *)src)->group->src_id))==NULL )
+ struct skill_unit *su = (struct skill_unit *)src;
+ int skillid, inf2;
+
+ nullpo_retr (-1, su);
+ nullpo_retr (-1, su->group);
+ skillid = su->group->skill_id;
+ inf2 = skill_get_inf2(skillid);
+ if( (ss=map_id2bl( su->group->src_id))==NULL )
return -1;
if(ss->prev == NULL)
return -1;
- if(inf2&0x80 &&
- (map[src->m].flag.pvp || pc_iskiller((struct map_session_data *)src, (struct map_session_data *)target)) && // [MouseJstr]
- !(target->type == BL_PC && pc_isinvisible((struct map_session_data *)target)))
- return 0;
+ if(inf2&0x80 &&
+ (map[src->m].flag.pvp ||
+ (skillid >= 115 && skillid <= 125 && map[src->m].flag.gvg)) &&
+ !(target->type == BL_PC && pc_isinvisible((struct map_session_data *)target)))
+ return 0;
if(ss == target) {
if(inf2&0x100)
return 0;
@@ -4826,10 +3795,33 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
return -1;
}
}
- // Mob‚Åmaster_id‚ª‚ ‚Á‚Äspecial_mob_ai‚È‚çA¢Š«Žå‚ð‹‚ß‚é
+
if( src->type==BL_MOB ){
struct mob_data *md=(struct mob_data *)src;
- if(md && md->master_id>0){
+ nullpo_retr (-1, md);
+
+ if(target->type == BL_PC) {
+ struct map_session_data *sd = (struct map_session_data *)target;
+ nullpo_retr (-1, sd);
+
+ if(md->class_ >= 1285 && md->class_ <= 1287){
+ struct guild_castle *gc = guild_mapname2gc (map[target->m].name);
+ if(gc && agit_flag==0) // Guardians will not attack during non-woe time [Valaris]
+ return 1; // end addition [Valaris]
+ if(gc && sd->status.guild_id > 0) {
+ struct guild *g=guild_search(sd->status.guild_id); // don't attack guild members [Valaris]
+ if(g && g->guild_id == gc->guild_id)
+ return 1;
+ if(g && guild_isallied(g,gc))
+ return 1;
+ }
+ }
+ // option to have monsters ignore GMs [Valaris]
+ if (battle_config.monsters_ignore_gm > 0 && pc_isGM(sd) >= battle_config.monsters_ignore_gm)
+ return 1;
+ }
+ // Mob‚Åmaster_id‚ª‚ ‚Á‚Äspecial_mob_ai‚È‚çA¢Š«Žå‚ð‹‚ß‚é
+ if(md->master_id>0){
if(md->master_id==target->id) // Žå‚È‚çm’è
return 1;
if(md->state.special_mob_ai){
@@ -4869,11 +3861,11 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
if(ss->type == BL_PET && target->type==BL_MOB)
return 0;
- s_p=battle_get_party_id(ss);
- s_g=battle_get_guild_id(ss);
+ s_p=status_get_party_id(ss);
+ s_g=status_get_guild_id(ss);
- t_p=battle_get_party_id(target);
- t_g=battle_get_guild_id(target);
+ t_p=status_get_party_id(target);
+ t_g=status_get_guild_id(target);
if(flag&0x10000) {
if(s_p && t_p && s_p == t_p) // “¯‚¶ƒp[ƒeƒB‚È‚çm’èi–¡•ûj
@@ -4896,7 +3888,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
if(su && su->group->target_flag==BCT_NOENEMY)
return 1;
else if (battle_config.pk_mode &&
- (((struct map_session_data*)ss)->status.class==0 || ((struct map_session_data*)target)->status.class==0 ||
+ (((struct map_session_data*)ss)->status.class_==0 || ((struct map_session_data*)target)->status.class_==0 ||
((struct map_session_data*)ss)->status.base_level < battle_config.pk_min_level ||
((struct map_session_data*)target)->status.base_level < battle_config.pk_min_level))
return 1; // prevent novice engagement in pk_mode [Valaris]
@@ -4939,7 +3931,6 @@ int battle_check_range(struct block_list *src,struct block_list *bl,int range)
{
int dx,dy;
- struct walkpath_data wpd;
int arange;
nullpo_retr(0, src);
@@ -4962,16 +3953,7 @@ int battle_check_range(struct block_list *src,struct block_list *bl,int range)
// return 1;
// áŠQ•¨”»’è
- wpd.path_len=0;
- wpd.path_pos=0;
- wpd.path_half=0;
- if(path_search(&wpd,src->m,src->x,src->y,bl->x,bl->y,0x10001)!=-1)
- return 1;
-
- dx=(dx>0)?1:((dx<0)?-1:0);
- dy=(dy>0)?1:((dy<0)?-1:0);
- return (path_search(&wpd,src->m,src->x+dx,src->y+dy,
- bl->x-dx,bl->y-dy,0x10001)!=-1)?1:0;
+ return path_search_long(NULL,src->m,src->x,src->y,bl->x,bl->y);
}
/*==========================================
@@ -4989,7 +3971,7 @@ int battle_config_switch(const char *str) {
static const struct {
char str[128];
- int *val;
+ void *val;
} battle_data[] = {
{ "warp_point_debug", &battle_config.warp_point_debug },
{ "enemy_critical", &battle_config.enemy_critical },
@@ -5045,7 +4027,6 @@ static const struct {
{ "player_skillup_limit", &battle_config.skillup_limit },
{ "weapon_produce_rate", &battle_config.wp_rate },
{ "potion_produce_rate", &battle_config.pp_rate },
- { "deadly_potion_produce_rate", &battle_config.cdp_rate },
{ "monster_active_enable", &battle_config.monster_active_enable },
{ "monster_damage_delay_rate", &battle_config.monster_damage_delay_rate},
{ "monster_loot_type", &battle_config.monster_loot_type },
@@ -5082,6 +4063,11 @@ static const struct {
{ "natural_heal_skill_interval", &battle_config.natural_heal_skill_interval},
{ "natural_heal_weight_rate", &battle_config.natural_heal_weight_rate },
{ "item_name_override_grffile", &battle_config.item_name_override_grffile},
+ { "item_equip_override_grffile", &battle_config.item_equip_override_grffile}, // [Celest]
+ { "item_slots_override_grffile", &battle_config.item_slots_override_grffile}, // [Celest]
+ { "indoors_override_grffile", &battle_config.indoors_override_grffile}, // [Celest]
+ { "skill_sp_override_grffile", &battle_config.skill_sp_override_grffile}, // [Celest]
+ { "cardillust_read_grffile", &battle_config.cardillust_read_grffile}, // [Celest]
{ "arrow_decrement", &battle_config.arrow_decrement },
{ "max_aspd", &battle_config.max_aspd },
{ "max_hp", &battle_config.max_hp },
@@ -5099,14 +4085,14 @@ static const struct {
{ "undead_detect_type", &battle_config.undead_detect_type },
{ "player_auto_counter_type", &battle_config.pc_auto_counter_type },
{ "monster_auto_counter_type", &battle_config.monster_auto_counter_type},
- { "agi_penaly_type", &battle_config.agi_penaly_type },
- { "agi_penaly_count", &battle_config.agi_penaly_count },
- { "agi_penaly_num", &battle_config.agi_penaly_num },
- { "agi_penaly_count_lv", &battle_config.agi_penaly_count_lv },
- { "vit_penaly_type", &battle_config.vit_penaly_type },
- { "vit_penaly_count", &battle_config.vit_penaly_count },
- { "vit_penaly_num", &battle_config.vit_penaly_num },
- { "vit_penaly_count_lv", &battle_config.vit_penaly_count_lv },
+ { "agi_penalty_type", &battle_config.agi_penalty_type },
+ { "agi_penalty_count", &battle_config.agi_penalty_count },
+ { "agi_penalty_num", &battle_config.agi_penalty_num },
+ { "agi_penalty_count_lv", &battle_config.agi_penalty_count_lv },
+ { "vit_penalty_type", &battle_config.vit_penalty_type },
+ { "vit_penalty_count", &battle_config.vit_penalty_count },
+ { "vit_penalty_num", &battle_config.vit_penalty_num },
+ { "vit_penalty_count_lv", &battle_config.vit_penalty_count_lv },
{ "player_defense_type", &battle_config.player_defense_type },
{ "monster_defense_type", &battle_config.monster_defense_type },
{ "pet_defense_type", &battle_config.pet_defense_type },
@@ -5127,7 +4113,7 @@ static const struct {
{ "monster_attack_direction_change", &battle_config.monster_attack_direction_change },
{ "player_land_skill_limit", &battle_config.pc_land_skill_limit },
{ "monster_land_skill_limit", &battle_config.monster_land_skill_limit},
- { "party_skill_penaly", &battle_config.party_skill_penaly },
+ { "party_skill_penalty", &battle_config.party_skill_penalty },
{ "monster_class_change_full_recover", &battle_config.monster_class_change_full_recover },
{ "produce_item_name_input", &battle_config.produce_item_name_input },
{ "produce_potion_name_input", &battle_config.produce_potion_name_input},
@@ -5140,7 +4126,6 @@ static const struct {
{ "dead_branch_active", &battle_config.dead_branch_active },
{ "vending_max_value", &battle_config.vending_max_value },
{ "show_steal_in_same_party", &battle_config.show_steal_in_same_party },
- { "enable_upper_class", &battle_config.enable_upper_class },
{ "pet_attack_attr_none", &battle_config.pet_attack_attr_none },
{ "mob_attack_attr_none", &battle_config.mob_attack_attr_none },
{ "mob_ghostring_fix", &battle_config.mob_ghostring_fix },
@@ -5156,8 +4141,15 @@ static const struct {
{ "invite_request_check", &battle_config.invite_request_check },
{ "skill_removetrap_type", &battle_config.skill_removetrap_type },
{ "disp_experience", &battle_config.disp_experience },
- { "castle_defense_rate", &battle_config.castle_defense_rate },
- { "riding_weight", &battle_config.riding_weight },
+ { "castle_defense_rate", &battle_config.castle_defense_rate },
+ { "hp_rate", &battle_config.hp_rate },
+ { "sp_rate", &battle_config.sp_rate },
+ { "gm_can_drop_lv", &battle_config.gm_can_drop_lv },
+ { "disp_hpmeter", &battle_config.disp_hpmeter },
+ { "bone_drop", &battle_config.bone_drop },
+ { "monster_damage_delay", &battle_config.monster_damage_delay },
+
+// eAthena additions
{ "item_rate_common", &battle_config.item_rate_common }, // Added by RoVeRT
{ "item_rate_equip", &battle_config.item_rate_equip },
{ "item_rate_card", &battle_config.item_rate_card }, // End Addition
@@ -5198,16 +4190,23 @@ static const struct {
{ "max_cloth_color", &battle_config.max_cloth_color }, // added by [MouseJstr]
{ "castrate_dex_scale", &battle_config.castrate_dex_scale }, // added by [MouseJstr]
{ "area_size", &battle_config.area_size }, // added by [MouseJstr]
- { "muting_players", &battle_config.muting_players}, // added by [Apple]
+ { "muting_players", &battle_config.muting_players}, // added by [Apple]
{ "zeny_from_mobs", &battle_config.zeny_from_mobs}, // [Valaris]
{ "mobs_level_up", &battle_config.mobs_level_up}, // [Valaris]
{ "pk_min_level", &battle_config.pk_min_level}, // [celest]
{ "skill_steal_type", &battle_config.skill_steal_type}, // [celest]
{ "skill_steal_rate", &battle_config.skill_steal_rate}, // [celest]
{ "night_darkness_level", &battle_config.night_darkness_level}, // [celest]
+ { "motd_type", &battle_config.motd_type}, // [celest]
+ { "allow_atcommand_when_mute", &battle_config.allow_atcommand_when_mute}, // [celest]
+ { "finding_ore_rate", &battle_config.finding_ore_rate}, // [celest]
+ { "exp_calc_type", &battle_config.exp_calc_type}, // [celest]
+ { "min_skill_delay_limit", &battle_config.min_skill_delay_limit}, // [celest]
+ { "require_glory_guild", &battle_config.require_glory_guild}, // [celest]
+ { "idle_no_share", &battle_config.idle_no_share}, // [celest], for a feature by [MouseJstr]
//SQL-only options start
-#ifndef TXT_ONLY
+#ifndef TXT_ONLY
{ "mail_system", &battle_config.mail_system }, // added by [Valaris]
//SQL-only options end
#endif
@@ -5217,7 +4216,7 @@ int battle_set_value(char *w1, char *w2) {
int i;
for(i = 0; i < sizeof(battle_data) / (sizeof(battle_data[0])); i++)
if (strcmpi(w1, battle_data[i].str) == 0) {
- *battle_data[i].val = battle_config_switch(w2);
+ *((unsigned int *) battle_data[i].val) = battle_config_switch(w2);
return 1;
}
return 0;
@@ -5276,7 +4275,6 @@ void battle_set_defaults() {
battle_config.skillup_limit = 0;
battle_config.wp_rate=100;
battle_config.pp_rate=100;
- battle_config.cdp_rate=100;
battle_config.monster_active_enable=1;
battle_config.monster_damage_delay_rate=100;
battle_config.monster_loot_type=0;
@@ -5313,6 +4311,11 @@ void battle_set_defaults() {
battle_config.natural_heal_skill_interval=10000;
battle_config.natural_heal_weight_rate=50;
battle_config.item_name_override_grffile=1;
+ battle_config.item_equip_override_grffile=0; // [Celest]
+ battle_config.item_slots_override_grffile=0; // [Celest]
+ battle_config.indoors_override_grffile=0; // [Celest]
+ battle_config.skill_sp_override_grffile=0; // [Celest]
+ battle_config.cardillust_read_grffile=0; // [Celest]
battle_config.arrow_decrement=1;
battle_config.max_aspd = 199;
battle_config.max_hp = 32500;
@@ -5330,14 +4333,14 @@ void battle_set_defaults() {
battle_config.undead_detect_type = 0;
battle_config.pc_auto_counter_type = 1;
battle_config.monster_auto_counter_type = 1;
- battle_config.agi_penaly_type = 0;
- battle_config.agi_penaly_count = 3;
- battle_config.agi_penaly_num = 0;
- battle_config.agi_penaly_count_lv = ATK_FLEE;
- battle_config.vit_penaly_type = 0;
- battle_config.vit_penaly_count = 3;
- battle_config.vit_penaly_num = 0;
- battle_config.vit_penaly_count_lv = ATK_DEF;
+ battle_config.agi_penalty_type = 0;
+ battle_config.agi_penalty_count = 3;
+ battle_config.agi_penalty_num = 0;
+ battle_config.agi_penalty_count_lv = ATK_FLEE;
+ battle_config.vit_penalty_type = 0;
+ battle_config.vit_penalty_count = 3;
+ battle_config.vit_penalty_num = 0;
+ battle_config.vit_penalty_count_lv = ATK_DEF;
battle_config.player_defense_type = 0;
battle_config.monster_defense_type = 0;
battle_config.pet_defense_type = 0;
@@ -5349,17 +4352,16 @@ void battle_set_defaults() {
battle_config.pc_cloak_check_type = 0;
battle_config.monster_cloak_check_type = 0;
battle_config.gvg_short_damage_rate = 100;
- battle_config.gvg_long_damage_rate = 100;
- battle_config.gvg_magic_damage_rate = 100;
- battle_config.gvg_misc_damage_rate = 100;
+ battle_config.gvg_long_damage_rate = 60;
+ battle_config.gvg_magic_damage_rate = 50;
+ battle_config.gvg_misc_damage_rate = 60;
battle_config.gvg_eliminate_time = 7000;
battle_config.mob_changetarget_byskill = 0;
battle_config.pc_attack_direction_change = 1;
battle_config.monster_attack_direction_change = 1;
- battle_config.pc_undead_nofreeze = 0;
battle_config.pc_land_skill_limit = 1;
battle_config.monster_land_skill_limit = 1;
- battle_config.party_skill_penaly = 1;
+ battle_config.party_skill_penalty = 1;
battle_config.monster_class_change_full_recover = 0;
battle_config.produce_item_name_input = 1;
battle_config.produce_potion_name_input = 1;
@@ -5372,7 +4374,6 @@ void battle_set_defaults() {
battle_config.dead_branch_active = 0;
battle_config.vending_max_value = 10000000;
battle_config.show_steal_in_same_party = 0;
- battle_config.enable_upper_class = 0;
battle_config.pet_attack_attr_none = 0;
battle_config.pc_attack_attr_none = 0;
battle_config.mob_attack_attr_none = 1;
@@ -5388,6 +4389,15 @@ void battle_set_defaults() {
battle_config.invite_request_check = 1;
battle_config.skill_removetrap_type = 0;
battle_config.disp_experience = 0;
+ battle_config.castle_defense_rate = 100;
+ battle_config.hp_rate = 100;
+ battle_config.sp_rate = 100;
+ battle_config.gm_can_drop_lv = 0;
+ battle_config.disp_hpmeter = 0;
+ battle_config.bone_drop = 0;
+ battle_config.monster_damage_delay = 1;
+
+// eAthena additions
battle_config.item_rate_common = 100;
battle_config.item_rate_equip = 100;
battle_config.item_rate_card = 100;
@@ -5421,7 +4431,7 @@ void battle_set_defaults() {
battle_config.ban_spoof_namer = 5; // added by [Yor] (default: 5 minutes)
battle_config.hack_info_GM_level = 60; // added by [Yor] (default: 60, GM level)
battle_config.any_warp_GM_min_level = 20; // added by [Yor]
- battle_config.packet_ver_flag = 511; // added by [Yor]
+ battle_config.packet_ver_flag = 255; // added by [Yor]
battle_config.min_hair_style = 0;
battle_config.max_hair_style = 20;
battle_config.min_hair_color = 0;
@@ -5434,13 +4444,18 @@ void battle_set_defaults() {
battle_config.skill_steal_type = 1;
battle_config.skill_steal_rate = 100;
battle_config.night_darkness_level = 9;
-
+ battle_config.motd_type = 0;
+ battle_config.allow_atcommand_when_mute = 0;
+ battle_config.finding_ore_rate = 100;
battle_config.castrate_dex_scale = 150;
-
battle_config.area_size = 14;
+ battle_config.exp_calc_type = 1;
+ battle_config.min_skill_delay_limit = 100;
+ battle_config.require_glory_guild = 0;
+ battle_config.idle_no_share = 0;
//SQL-only options start
-#ifndef TXT_ONLY
+#ifndef TXT_ONLY
battle_config.mail_system = 0;
//SQL-only options end
#endif
@@ -5477,6 +4492,10 @@ void battle_validate_conf() {
battle_config.max_aspd = 10;
if(battle_config.max_aspd > 1000)
battle_config.max_aspd = 1000;
+ if(battle_config.hp_rate < 0)
+ battle_config.hp_rate = 1;
+ if(battle_config.sp_rate < 0)
+ battle_config.sp_rate = 1;
if(battle_config.max_hp > 1000000)
battle_config.max_hp = 1000000;
if(battle_config.max_hp < 100)
@@ -5495,10 +4514,10 @@ void battle_validate_conf() {
battle_config.max_cart_weight = 100;
battle_config.max_cart_weight *= 10;
- if(battle_config.agi_penaly_count < 2)
- battle_config.agi_penaly_count = 2;
- if(battle_config.vit_penaly_count < 2)
- battle_config.vit_penaly_count = 2;
+ if(battle_config.agi_penalty_count < 2)
+ battle_config.agi_penalty_count = 2;
+ if(battle_config.vit_penalty_count < 2)
+ battle_config.vit_penalty_count = 2;
if(battle_config.guild_exp_limit > 99)
battle_config.guild_exp_limit = 99;
@@ -5530,11 +4549,11 @@ void battle_validate_conf() {
battle_config.night_at_start = 0;
else if (battle_config.night_at_start > 1) // added by [Yor]
battle_config.night_at_start = 1;
- if (battle_config.day_duration < 0) // added by [Yor]
- battle_config.day_duration = 0;
- if (battle_config.night_duration < 0) // added by [Yor]
- battle_config.night_duration = 0;
-
+ if (battle_config.day_duration != 0 && battle_config.day_duration < 60000) // added by [Yor]
+ battle_config.day_duration = 60000;
+ if (battle_config.night_duration != 0 && battle_config.night_duration < 60000) // added by [Yor]
+ battle_config.night_duration = 60000;
+
if (battle_config.ban_spoof_namer < 0) // added by [Yor]
battle_config.ban_spoof_namer = 0;
else if (battle_config.ban_spoof_namer > 32767)
@@ -5551,33 +4570,43 @@ void battle_validate_conf() {
battle_config.any_warp_GM_min_level = 100;
// at least 1 client must be accepted
- if ((battle_config.packet_ver_flag & 511) == 0) // added by [Yor]
- battle_config.packet_ver_flag = 511; // accept all clients
-
+ if ((battle_config.packet_ver_flag & 255) == 0) // added by [Yor]
+ battle_config.packet_ver_flag = 255; // accept all clients
+
if (battle_config.night_darkness_level > 10) // Celest
battle_config.night_darkness_level = 10;
+ if (battle_config.motd_type < 0)
+ battle_config.motd_type = 0;
+ else if (battle_config.motd_type > 1)
+ battle_config.motd_type = 1;
+
+ if (battle_config.finding_ore_rate < 0)
+ battle_config.finding_ore_rate = 0;
+
if (battle_config.vending_max_value > 10000000 || battle_config.vending_max_value<=0) // Lupus & Kobra_k88
battle_config.vending_max_value = 10000000;
+ if (battle_config.min_skill_delay_limit < 10)
+ battle_config.min_skill_delay_limit = 10; // minimum delay of 10ms
}
/*==========================================
* Ý’èƒtƒ@ƒCƒ‹‚ð“ǂݞ‚Þ
*------------------------------------------
*/
-int battle_config_read(const char *cfgName)
+int battle_config_read(const char *cfgName)
{
char line[1024], w1[1024], w2[1024];
FILE *fp;
static int count = 0;
- if ((count++) == 0)
+ if ((count++) == 0)
battle_set_defaults();
fp = fopen(cfgName,"r");
if (fp == NULL) {
- printf("file not found: %s\n", cfgName);
+ printf("File not found: %s\n", cfgName);
return 1;
}
while(fgets(line,1020,fp)){
diff --git a/src/map/battle.h b/src/map/battle.h
index f6f0345ca..393cc58b4 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -63,50 +63,6 @@ int battle_weapon_attack( struct block_list *bl,struct block_list *target,
// ŠeŽíƒpƒ‰ƒ[ƒ^‚𓾂é
int battle_counttargeted(struct block_list *bl,struct block_list *src,int target_lv);
-int battle_get_class(struct block_list *bl);
-int battle_get_dir(struct block_list *bl);
-int battle_get_lv(struct block_list *bl);
-int battle_get_range(struct block_list *bl);
-int battle_get_hp(struct block_list *bl);
-int battle_get_max_hp(struct block_list *bl);
-int battle_get_str(struct block_list *bl);
-int battle_get_agi(struct block_list *bl);
-int battle_get_vit(struct block_list *bl);
-int battle_get_int(struct block_list *bl);
-int battle_get_dex(struct block_list *bl);
-int battle_get_luk(struct block_list *bl);
-int battle_get_hit(struct block_list *bl);
-int battle_get_flee(struct block_list *bl);
-int battle_get_def(struct block_list *bl);
-int battle_get_mdef(struct block_list *bl);
-int battle_get_flee2(struct block_list *bl);
-int battle_get_def2(struct block_list *bl);
-int battle_get_mdef2(struct block_list *bl);
-int battle_get_baseatk(struct block_list *bl);
-int battle_get_atk(struct block_list *bl);
-int battle_get_atk2(struct block_list *bl);
-int battle_get_speed(struct block_list *bl);
-int battle_get_adelay(struct block_list *bl);
-int battle_get_amotion(struct block_list *bl);
-int battle_get_dmotion(struct block_list *bl);
-int battle_get_element(struct block_list *bl);
-int battle_get_attack_element(struct block_list *bl);
-int battle_get_attack_element2(struct block_list *bl); //¶Žè•Ší‘®«Žæ“¾
-#define battle_get_elem_type(bl) (battle_get_element(bl)%10)
-#define battle_get_elem_level(bl) (battle_get_element(bl)/10/2)
-int battle_get_party_id(struct block_list *bl);
-int battle_get_guild_id(struct block_list *bl);
-int battle_get_race(struct block_list *bl);
-int battle_get_size(struct block_list *bl);
-int battle_get_mode(struct block_list *bl);
-int battle_get_mexp(struct block_list *bl);
-
-struct status_change *battle_get_sc_data(struct block_list *bl);
-short *battle_get_sc_count(struct block_list *bl);
-short *battle_get_opt1(struct block_list *bl);
-short *battle_get_opt2(struct block_list *bl);
-short *battle_get_opt3(struct block_list *bl);
-short *battle_get_option(struct block_list *bl);
enum {
BCT_NOENEMY =0x00000,
@@ -115,6 +71,7 @@ enum {
BCT_NOPARTY =0x50000,
BCT_ALL =0x20000,
BCT_NOONE =0x60000,
+ BCT_SELF =0x60000,
};
int battle_check_undead(int race,int element);
@@ -174,7 +131,6 @@ extern struct Battle_Config {
int skillup_limit;
int wp_rate;
int pp_rate;
- int cdp_rate;
int monster_active_enable;
int monster_damage_delay_rate;
int monster_loot_type;
@@ -212,12 +168,17 @@ extern struct Battle_Config {
int natural_heal_skill_interval;
int natural_heal_weight_rate;
int item_name_override_grffile;
+ int indoors_override_grffile; // [Celest]
+ int skill_sp_override_grffile; // [Celest]
+ int cardillust_read_grffile;
+ int item_equip_override_grffile;
+ int item_slots_override_grffile;
int arrow_decrement;
int max_aspd;
int max_hp;
int max_sp;
int max_lv;
- int max_parameter;
+ unsigned int max_parameter;
int max_cart_weight;
int pc_skill_log;
int mob_skill_log;
@@ -229,12 +190,12 @@ extern struct Battle_Config {
int undead_detect_type;
int pc_auto_counter_type;
int monster_auto_counter_type;
- int agi_penaly_type;
- int agi_penaly_count;
- int agi_penaly_num;
- int vit_penaly_type;
- int vit_penaly_count;
- int vit_penaly_num;
+ int agi_penalty_type;
+ int agi_penalty_count;
+ int agi_penalty_num;
+ int vit_penalty_type;
+ int vit_penalty_count;
+ int vit_penalty_num;
int player_defense_type;
int monster_defense_type;
int pet_defense_type;
@@ -253,10 +214,9 @@ extern struct Battle_Config {
int mob_changetarget_byskill;
int pc_attack_direction_change;
int monster_attack_direction_change;
- int pc_undead_nofreeze;
int pc_land_skill_limit;
int monster_land_skill_limit;
- int party_skill_penaly;
+ int party_skill_penalty;
int monster_class_change_full_recover;
int produce_item_name_input;
int produce_potion_name_input;
@@ -271,7 +231,6 @@ extern struct Battle_Config {
// int pet_lootitem; // removed [Valaris]
// int pet_weight; // removed [Valaris]
int show_steal_in_same_party;
- int enable_upper_class;
int pet_attack_attr_none;
int mob_attack_attr_none;
int mob_ghostring_fix;
@@ -287,7 +246,7 @@ extern struct Battle_Config {
int prevent_logout; // Added by RoVeRT
int alchemist_summon_reward; // [Valaris]
- int maximum_level;
+ unsigned int maximum_level;
int drops_by_luk;
int monsters_ignore_gm;
int equipment_breaking;
@@ -297,8 +256,8 @@ extern struct Battle_Config {
int pk_mode;
int show_mob_hp; // end additions [Valaris]
- int agi_penaly_count_lv;
- int vit_penaly_count_lv;
+ int agi_penalty_count_lv;
+ int vit_penalty_count_lv;
int gx_allhit;
int gx_cardfix;
@@ -312,18 +271,25 @@ extern struct Battle_Config {
int skill_removetrap_type;
int disp_experience;
int castle_defense_rate;
- int riding_weight;
int backstab_bow_penalty;
+ int hp_rate;
+ int sp_rate;
+ int gm_can_drop_lv;
+ int disp_hpmeter;
+ int bone_drop;
+ int monster_damage_delay;
+// eAthena additions
int night_at_start; // added by [Yor]
int day_duration; // added by [Yor]
int night_duration; // added by [Yor]
int ban_spoof_namer; // added by [Yor]
+ int ban_hack_trade; // added by [Yor]
int hack_info_GM_level; // added by [Yor]
int any_warp_GM_min_level; // added by [Yor]
int packet_ver_flag; // added by [Yor]
- int muting_players; // added by [Apple]
-
+ int muting_players; // added by [PoW]
+
int min_hair_style; // added by [MouseJstr]
int max_hair_style; // added by [MouseJstr]
int min_hair_color; // added by [MouseJstr]
@@ -336,10 +302,17 @@ extern struct Battle_Config {
int zeny_from_mobs; // [Valaris]
int mobs_level_up; // [Valaris]
- int pk_min_level; // [celest]
+ unsigned int pk_min_level; // [celest]
int skill_steal_type; // [celest]
int skill_steal_rate; // [celest]
int night_darkness_level; // [celest]
+ int motd_type; // [celest]
+ int allow_atcommand_when_mute; // [celest]
+ int finding_ore_rate; // orn
+ int exp_calc_type;
+ int min_skill_delay_limit;
+ int require_glory_guild;
+ int idle_no_share;
#ifndef TXT_ONLY /* SQL-only options */
int mail_system; // [Valaris]
diff --git a/src/map/charcommand.c b/src/map/charcommand.c
index de05e20ae..9b700dc47 100644
--- a/src/map/charcommand.c
+++ b/src/map/charcommand.c
@@ -15,6 +15,7 @@
#include "itemdb.h"
#include "map.h"
#include "pc.h"
+#include "status.h"
#include "skill.h"
#include "mob.h"
#include "pet.h"
@@ -27,10 +28,11 @@
#include "npc.h"
#include "trade.h"
#include "core.h"
+#include "showmsg.h"
static char command_symbol = '#';
-static char msg_table[1000][1024]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others)
+extern char *msg_table[1000]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others)
#define CCMD_FUNC(x) int charcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message)
@@ -42,6 +44,15 @@ CCMD_FUNC(option);
CCMD_FUNC(save);
CCMD_FUNC(stats_all);
CCMD_FUNC(reset);
+CCMD_FUNC(spiritball);
+CCMD_FUNC(itemlist);
+CCMD_FUNC(effect);
+CCMD_FUNC(storagelist);
+CCMD_FUNC(item);
+CCMD_FUNC(warp);
+CCMD_FUNC(zeny);
+CCMD_FUNC(showexp);
+CCMD_FUNC(showdelay);
#ifdef TXT_ONLY
/* TXT_ONLY */
@@ -70,6 +81,18 @@ static CharCommandInfo charcommand_info[] = {
{ CharCommandReset, "#reset", 60, charcommand_reset },
{ CharCommandSave, "#save", 60, charcommand_save },
{ CharCommandStatsAll, "#statsall", 40, charcommand_stats_all },
+ { CharCommandSpiritball, "#spiritball", 40, charcommand_spiritball },
+ { CharCommandItemList, "#itemlist", 40, charcommand_itemlist },
+ { CharCommandEffect, "#effect", 40, charcommand_effect },
+ { CharCommandStorageList, "#storagelist", 40, charcommand_storagelist },
+ { CharCommandItem, "#item", 60, charcommand_item },
+ { CharCommandWarp, "#warp", 60, charcommand_warp },
+ { CharCommandWarp, "#rura", 60, charcommand_warp },
+ { CharCommandWarp, "#rura+", 60, charcommand_warp },
+ { CharCommandZeny, "#zeny", 60, charcommand_zeny },
+ { CharCommandShowExp, "#showexp", 0, charcommand_showexp},
+ { CharCommandShowDelay, "#showdelay", 0, charcommand_showdelay},
+
#ifdef TXT_ONLY
/* TXT_ONLY */
@@ -248,8 +271,8 @@ int charcommand_config_read(const char *cfgName) {
charcommand_config_read(w2);
else if (strcmpi(w1, "command_symbol") == 0 && w2[0] > 31 &&
w2[0] != '/' && // symbol of standard ragnarok GM commands
- w2[0] != '%' && // symbol of party chat speaking
- w2[0] != '@') // symbol for @commands
+ w2[0] != '%' // symbol of party chat speaking
+ )
command_symbol = w2[0];
}
fclose(fp);
@@ -285,23 +308,24 @@ int charcommand_jobchange(
}
if ((pl_sd = map_nick2sd(character)) != NULL) {
+ int j;
if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can change job only to lower or same level
if ((job >= 0 && job < MAX_PC_CLASS)) {
// fix pecopeco display
if ((job != 13 && job != 21 && job != 4014 && job != 4022)) {
if (pc_isriding(sd)) {
- if (pl_sd->status.class == 13)
- pl_sd->status.class = pl_sd->view_class = 7;
- if (pl_sd->status.class == 21)
- pl_sd->status.class = pl_sd->view_class = 14;
- if (pl_sd->status.class == 4014)
- pl_sd->status.class = pl_sd->view_class = 4008;
- if (pl_sd->status.class == 4022)
- pl_sd->status.class = pl_sd->view_class = 4015;
+ if (pl_sd->status.class_ == 13)
+ pl_sd->status.class_ = pl_sd->view_class = 7;
+ if (pl_sd->status.class_ == 21)
+ pl_sd->status.class_ = pl_sd->view_class = 14;
+ if (pl_sd->status.class_ == 4014)
+ pl_sd->status.class_ = pl_sd->view_class = 4008;
+ if (pl_sd->status.class_ == 4022)
+ pl_sd->status.class_ = pl_sd->view_class = 4015;
pl_sd->status.option &= ~0x0020;
clif_changeoption(&pl_sd->bl);
- pc_calcstatus(pl_sd, 0);
+ status_calc_pc(pl_sd, 0);
}
} else {
if (!pc_isriding(sd)) {
@@ -315,7 +339,10 @@ int charcommand_jobchange(
job = 4015;
}
}
-
+ for (j=0; j < MAX_INVENTORY; j++) {
+ if(pl_sd->status.inventory[j].nameid>0 && pl_sd->status.inventory[j].equip!=0)
+ pc_unequipitem(pl_sd, j, 3);
+ }
if (pc_jobchange(pl_sd, job, upper) == 0)
clif_displaymessage(fd, msg_table[48]); // Character's job changed.
else {
@@ -412,9 +439,9 @@ int charcommand_petfriendly(
if ((pl_sd->pet.intimate > 0 && t <= 0) ||
(pl_sd->pet.intimate <= 0 && t > 0)) {
if (pl_sd->bl.prev != NULL)
- pc_calcstatus(pl_sd, 0);
+ status_calc_pc(pl_sd, 0);
else
- pc_calcstatus(pl_sd, 2);
+ status_calc_pc(pl_sd, 2);
}
}
clif_displaymessage(pl_sd->fd, msg_table[182]); // Pet friendly value changed!
@@ -481,7 +508,7 @@ int charcommand_stats(
{ "Zeny - %d", pl_sd->status.zeny },
{ NULL, 0 }
};
- sprintf(job_jobname, "Job - %s %s", job_name(pl_sd->status.class), "(level %d)");
+ sprintf(job_jobname, "Job - %s %s", job_name(pl_sd->status.class_), "(level %d)");
sprintf(output, msg_table[53], pl_sd->status.name); // '%s' stats:
clif_displaymessage(fd, output);
for (i = 0; output_table[i].format != NULL; i++) {
@@ -561,37 +588,37 @@ int charcommand_option(
pl_sd->opt2 = opt2;
pl_sd->status.option = opt3;
// fix pecopeco display
- if (pl_sd->status.class == 13 || pl_sd->status.class == 21 || pl_sd->status.class == 4014 || pl_sd->status.class == 4022) {
+ if (pl_sd->status.class_ == 13 || pl_sd->status.class_ == 21 || pl_sd->status.class_ == 4014 || pl_sd->status.class_ == 4022) {
if (!pc_isriding(pl_sd)) { // pl_sd have the new value...
- if (pl_sd->status.class == 13)
- pl_sd->status.class = pl_sd->view_class = 7;
- else if (pl_sd->status.class == 21)
- pl_sd->status.class = pl_sd->view_class = 14;
- else if (pl_sd->status.class == 4014)
- pl_sd->status.class = pl_sd->view_class = 4008;
- else if (pl_sd->status.class == 4022)
- pl_sd->status.class = pl_sd->view_class = 4015;
+ if (pl_sd->status.class_ == 13)
+ pl_sd->status.class_ = pl_sd->view_class = 7;
+ else if (pl_sd->status.class_ == 21)
+ pl_sd->status.class_ = pl_sd->view_class = 14;
+ else if (pl_sd->status.class_ == 4014)
+ pl_sd->status.class_ = pl_sd->view_class = 4008;
+ else if (pl_sd->status.class_ == 4022)
+ pl_sd->status.class_ = pl_sd->view_class = 4015;
}
} else {
if (pc_isriding(pl_sd)) { // pl_sd have the new value...
if (pl_sd->disguise > 0) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris] (code added by [Yor])
pl_sd->status.option &= ~0x0020;
} else {
- if (pl_sd->status.class == 7)
- pl_sd->status.class = pl_sd->view_class = 13;
- else if (pl_sd->status.class == 14)
- pl_sd->status.class = pl_sd->view_class = 21;
- else if (pl_sd->status.class == 4008)
- pl_sd->status.class = pl_sd->view_class = 4014;
- else if (pl_sd->status.class == 4015)
- pl_sd->status.class = pl_sd->view_class = 4022;
+ if (pl_sd->status.class_ == 7)
+ pl_sd->status.class_ = pl_sd->view_class = 13;
+ else if (pl_sd->status.class_ == 14)
+ pl_sd->status.class_ = pl_sd->view_class = 21;
+ else if (pl_sd->status.class_ == 4008)
+ pl_sd->status.class_ = pl_sd->view_class = 4014;
+ else if (pl_sd->status.class_ == 4015)
+ pl_sd->status.class_ = pl_sd->view_class = 4022;
else
pl_sd->status.option &= ~0x0020;
}
}
}
clif_changeoption(&pl_sd->bl);
- pc_calcstatus(pl_sd, 0);
+ status_calc_pc(pl_sd, 0);
clif_displaymessage(fd, msg_table[58]); // Character's options changed.
} else {
clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
@@ -673,14 +700,14 @@ int charcommand_stats_all(const int fd, struct map_session_data* sd, const char*
count = 0;
for(i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) {
if (pc_isGM(pl_sd) > 0)
sprintf(gmlevel, "| GM Lvl: %d", pc_isGM(pl_sd));
else
sprintf(gmlevel, " ");
- sprintf(output, "Name: %s | BLvl: %d | Job: %s (Lvl: %d) | HP: %d/%d | SP: %d/%d", pl_sd->status.name, pl_sd->status.base_level, job_name(pl_sd->status.class), pl_sd->status.job_level, pl_sd->status.hp, pl_sd->status.max_hp, pl_sd->status.sp, pl_sd->status.max_sp);
+ sprintf(output, "Name: %s | BLvl: %d | Job: %s (Lvl: %d) | HP: %d/%d | SP: %d/%d", pl_sd->status.name, pl_sd->status.base_level, job_name(pl_sd->status.class_), pl_sd->status.job_level, pl_sd->status.hp, pl_sd->status.max_hp, pl_sd->status.sp, pl_sd->status.max_sp);
clif_displaymessage(fd, output);
sprintf(output, "STR: %d | AGI: %d | VIT: %d | INT: %d | DEX: %d | LUK: %d | Zeny: %d %s", pl_sd->status.str, pl_sd->status.agi, pl_sd->status.vit, pl_sd->status.int_, pl_sd->status.dex, pl_sd->status.luk, pl_sd->status.zeny, gmlevel);
clif_displaymessage(fd, output);
@@ -701,3 +728,530 @@ int charcommand_stats_all(const int fd, struct map_session_data* sd, const char*
return 0;
}
+/*==========================================
+ * CharSpiritBall Function by PalasX
+ *------------------------------------------
+ */
+int charcommand_spiritball(const int fd, struct map_session_data* sd,const char* command, const char* message)
+{
+ struct map_session_data *pl_sd;
+ char character[100];
+ int spirit = 0;
+
+ memset(character, '\0', sizeof(character));
+
+ if(!message || !*message || sscanf(message, "%d %99[^\n]", &spirit, character) < 2 || spirit < 0 || spirit > 1000) {
+ clif_displaymessage(fd, "Usage: @spiritball <number: 0-1000>) <CHARACTER_NAME>.");
+ return -1;
+ }
+
+ if((pl_sd = map_nick2sd(character)) != NULL) {
+ if (spirit >= 0 && spirit <= 0x7FFF) {
+ if (pl_sd->spiritball != spirit || spirit > 999) {
+ if (pl_sd->spiritball > 0)
+ pc_delspiritball(pl_sd, pl_sd->spiritball, 1);
+ pl_sd->spiritball = spirit;
+ clif_spiritball(pl_sd);
+ // no message, player can look the difference
+ if (spirit > 1000)
+ clif_displaymessage(fd, msg_table[204]); // WARNING: more than 1000 spiritballs can CRASH your server and/or client!
+ } else {
+ clif_displaymessage(fd, msg_table[205]); // You already have this number of spiritballs.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[37]); // An invalid number was specified.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[3]); // Character not found.
+ return -1;
+ }
+ return 0;
+}
+
+/*==========================================
+ * #itemlist <character>: Displays the list of a player's items.
+ *------------------------------------------
+ */
+int
+charcommand_itemlist(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ struct map_session_data *pl_sd;
+ struct item_data *item_data, *item_temp;
+ int i, j, equip, count, counter, counter2;
+ char character[100], output[200], equipstr[100], outputtmp[200];
+ nullpo_retr(-1, sd);
+
+ memset(character, '\0', sizeof(character));
+ memset(output, '\0', sizeof(output));
+ memset(equipstr, '\0', sizeof(equipstr));
+ memset(outputtmp, '\0', sizeof(outputtmp));
+
+ if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ clif_displaymessage(fd, "Please, enter a player name (usage: #itemlist <char name>).");
+ return -1;
+ }
+
+ if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can look items only lower or same level
+ counter = 0;
+ count = 0;
+ for (i = 0; i < MAX_INVENTORY; i++) {
+ if (pl_sd->status.inventory[i].nameid > 0 && (item_data = itemdb_search(pl_sd->status.inventory[i].nameid)) != NULL) {
+ counter = counter + pl_sd->status.inventory[i].amount;
+ count++;
+ if (count == 1) {
+ sprintf(output, "------ Items list of '%s' ------", pl_sd->status.name);
+ clif_displaymessage(fd, output);
+ }
+ if ((equip = pl_sd->status.inventory[i].equip)) {
+ strcpy(equipstr, "| equiped: ");
+ if (equip & 4)
+ strcat(equipstr, "robe/gargment, ");
+ if (equip & 8)
+ strcat(equipstr, "left accessory, ");
+ if (equip & 16)
+ strcat(equipstr, "body/armor, ");
+ if ((equip & 34) == 2)
+ strcat(equipstr, "right hand, ");
+ if ((equip & 34) == 32)
+ strcat(equipstr, "left hand, ");
+ if ((equip & 34) == 34)
+ strcat(equipstr, "both hands, ");
+ if (equip & 64)
+ strcat(equipstr, "feet, ");
+ if (equip & 128)
+ strcat(equipstr, "right accessory, ");
+ if ((equip & 769) == 1)
+ strcat(equipstr, "lower head, ");
+ if ((equip & 769) == 256)
+ strcat(equipstr, "top head, ");
+ if ((equip & 769) == 257)
+ strcat(equipstr, "lower/top head, ");
+ if ((equip & 769) == 512)
+ strcat(equipstr, "mid head, ");
+ if ((equip & 769) == 512)
+ strcat(equipstr, "lower/mid head, ");
+ if ((equip & 769) == 769)
+ strcat(equipstr, "lower/mid/top head, ");
+ // remove final ', '
+ equipstr[strlen(equipstr) - 2] = '\0';
+ } else
+ memset(equipstr, '\0', sizeof(equipstr));
+ if (sd->status.inventory[i].refine)
+ sprintf(output, "%d %s %+d (%s %+d, id: %d) %s", pl_sd->status.inventory[i].amount, item_data->name, pl_sd->status.inventory[i].refine, item_data->jname, pl_sd->status.inventory[i].refine, pl_sd->status.inventory[i].nameid, equipstr);
+ else
+ sprintf(output, "%d %s (%s, id: %d) %s", pl_sd->status.inventory[i].amount, item_data->name, item_data->jname, pl_sd->status.inventory[i].nameid, equipstr);
+ clif_displaymessage(fd, output);
+ memset(output, '\0', sizeof(output));
+ counter2 = 0;
+ for (j = 0; j < item_data->slot; j++) {
+ if (pl_sd->status.inventory[i].card[j]) {
+ if ((item_temp = itemdb_search(pl_sd->status.inventory[i].card[j])) != NULL) {
+ if (output[0] == '\0')
+ sprintf(outputtmp, " -> (card(s): #%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname);
+ else
+ sprintf(outputtmp, "#%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname);
+ strcat(output, outputtmp);
+ }
+ }
+ }
+ if (output[0] != '\0') {
+ output[strlen(output) - 2] = ')';
+ output[strlen(output) - 1] = '\0';
+ clif_displaymessage(fd, output);
+ }
+ }
+ }
+ if (count == 0)
+ clif_displaymessage(fd, "No item found on this player.");
+ else {
+ sprintf(output, "%d item(s) found in %d kind(s) of items.", counter, count);
+ clif_displaymessage(fd, output);
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[3]); // Character not found.
+ return -1;
+ }
+
+ return 0;
+}
+
+/*==========================================
+ * #effect by [MouseJstr]
+ *
+ * Create a effect localized on another character
+ *------------------------------------------
+ */
+int
+charcommand_effect(const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ struct map_session_data *pl_sd = NULL;
+ char target[255];
+ int type = 0;
+ nullpo_retr(-1, sd);
+
+ if (!message || !*message || sscanf(message, "%d %s", &type, target) != 2) {
+ clif_displaymessage(fd, "usage: #effect <type+> <target>.");
+ return -1;
+ }
+
+ if((pl_sd=map_nick2sd((char *) target)) == NULL)
+ return -1;
+
+ clif_specialeffect(&pl_sd->bl, type, 0);
+ clif_displaymessage(fd, msg_table[229]); // Your effect has changed.
+
+ return 0;
+}
+
+/*==========================================
+ * #storagelist <character>: Displays the items list of a player's storage.
+ *------------------------------------------
+ */
+int
+charcommand_storagelist(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ struct storage *stor;
+ struct map_session_data *pl_sd;
+ struct item_data *item_data, *item_temp;
+ int i, j, count, counter, counter2;
+ char character[100], output[200], outputtmp[200];
+ nullpo_retr(-1, sd);
+
+ memset(character, '\0', sizeof(character));
+ memset(output, '\0', sizeof(output));
+ memset(outputtmp, '\0', sizeof(outputtmp));
+
+ if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) {
+ clif_displaymessage(fd, "Please, enter a player name (usage: #itemlist <char name>).");
+ return -1;
+ }
+
+ if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can look items only lower or same level
+ if((stor = account2storage2(pl_sd->status.account_id)) != NULL) {
+ counter = 0;
+ count = 0;
+ for (i = 0; i < MAX_STORAGE; i++) {
+ if (stor->storage_[i].nameid > 0 && (item_data = itemdb_search(stor->storage_[i].nameid)) != NULL) {
+ counter = counter + stor->storage_[i].amount;
+ count++;
+ if (count == 1) {
+ sprintf(output, "------ Storage items list of '%s' ------", pl_sd->status.name);
+ clif_displaymessage(fd, output);
+ }
+ if (stor->storage_[i].refine)
+ sprintf(output, "%d %s %+d (%s %+d, id: %d)", stor->storage_[i].amount, item_data->name, stor->storage_[i].refine, item_data->jname, stor->storage_[i].refine, stor->storage_[i].nameid);
+ else
+ sprintf(output, "%d %s (%s, id: %d)", stor->storage_[i].amount, item_data->name, item_data->jname, stor->storage_[i].nameid);
+ clif_displaymessage(fd, output);
+ memset(output, '\0', sizeof(output));
+ counter2 = 0;
+ for (j = 0; j < item_data->slot; j++) {
+ if (stor->storage_[i].card[j]) {
+ if ((item_temp = itemdb_search(stor->storage_[i].card[j])) != NULL) {
+ if (output[0] == '\0')
+ sprintf(outputtmp, " -> (card(s): #%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname);
+ else
+ sprintf(outputtmp, "#%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname);
+ strcat(output, outputtmp);
+ }
+ }
+ }
+ if (output[0] != '\0') {
+ output[strlen(output) - 2] = ')';
+ output[strlen(output) - 1] = '\0';
+ clif_displaymessage(fd, output);
+ }
+ }
+ }
+ if (count == 0)
+ clif_displaymessage(fd, "No item found in the storage of this player.");
+ else {
+ sprintf(output, "%d item(s) found in %d kind(s) of items.", counter, count);
+ clif_displaymessage(fd, output);
+ }
+ } else {
+ clif_displaymessage(fd, "This player has no storage.");
+ return 0;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[3]); // Character not found.
+ return -1;
+ }
+
+ return 0;
+}
+
+static void
+charcommand_giveitem_sub(struct map_session_data *sd,struct item_data *item_data,int number)
+{
+ int flag = 0;
+ int loop = 1, get_count = number,i;
+ struct item item_tmp;
+
+ if(sd && item_data){
+ if (item_data->type == 4 || item_data->type == 5 ||
+ item_data->type == 7 || item_data->type == 8) {
+ loop = number;
+ get_count = 1;
+ }
+ for (i = 0; i < loop; i++) {
+ memset(&item_tmp, 0, sizeof(item_tmp));
+ item_tmp.nameid = item_data->nameid;
+ item_tmp.identify = 1;
+ if ((flag = pc_additem((struct map_session_data*)sd,
+ &item_tmp, get_count)))
+ clif_additem((struct map_session_data*)sd, 0, 0, flag);
+ }
+ }
+}
+/*==========================================
+ * #item command (usage: #item <name/id_of_item> <quantity> <player>)
+ * by MC Cameri
+ *------------------------------------------
+ */
+int charcommand_item(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ char item_name[100];
+ char character[100];
+ struct map_session_data *pl_sd;
+ int number = 0, item_id, flag;
+ struct item item_tmp;
+ struct item_data *item_data;
+ int get_count, i, pet_id;
+ nullpo_retr(-1, sd);
+
+ memset(item_name, '\0', sizeof(item_name));
+
+ if (!message || !*message || sscanf(message, "%99s %d %99[^\n]", item_name, &number, character) < 3) {
+ clif_displaymessage(fd, "Please, enter an item name/id (usage: #item <item name or ID> <quantity> <char name>).");
+ return -1;
+ }
+
+ if (number <= 0)
+ number = 1;
+
+ item_id = 0;
+ if ((item_data = itemdb_searchname(item_name)) != NULL ||
+ (item_data = itemdb_exists(atoi(item_name))) != NULL)
+ item_id = item_data->nameid;
+
+ if (item_id >= 500) {
+ get_count = number;
+ // check pet egg
+ pet_id = search_petDB_index(item_id, PET_EGG);
+ if (item_data->type == 4 || item_data->type == 5 ||
+ item_data->type == 7 || item_data->type == 8) {
+ get_count = 1;
+ }
+ if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can look items only lower or same level
+ for (i = 0; i < number; i += get_count) {
+ // if pet egg
+ if (pet_id >= 0) {
+ pl_sd->catch_target_class = pet_db[pet_id].class_;
+ intif_create_pet(pl_sd->status.account_id, pl_sd->status.char_id,
+ (short)pet_db[pet_id].class_, (short)mob_db[pet_db[pet_id].class_].lv,
+ (short)pet_db[pet_id].EggID, 0, (short)pet_db[pet_id].intimate,
+ 100, 0, 1, pet_db[pet_id].jname);
+ // if not pet egg
+ } else {
+ memset(&item_tmp, 0, sizeof(item_tmp));
+ item_tmp.nameid = item_id;
+ item_tmp.identify = 1;
+ if ((flag = pc_additem(pl_sd, &item_tmp, get_count)))
+ clif_additem(pl_sd, 0, 0, flag);
+ }
+ }
+ clif_displaymessage(fd, msg_table[18]); // Item created.
+ } else {
+ clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
+ } else if(/* from jA's @giveitem */strcmpi(character,"all")==0 || strcmpi(character,"everyone")==0){
+ for (i = 0; i < fd_max; i++) {
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data)){
+ charcommand_giveitem_sub(pl_sd,item_data,number);
+ snprintf(tmp_output, sizeof(tmp_output), "You got %s %d.", item_name,number);
+ clif_displaymessage(pl_sd->fd, tmp_output);
+ }
+ }
+ snprintf(tmp_output, sizeof(tmp_output), "%s received %s %d.","Everyone",item_name,number);
+ clif_displaymessage(fd, tmp_output);
+ } else {
+ clif_displaymessage(fd, msg_table[3]); // Character not found.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[19]); // Invalid item ID or name.
+ return -1;
+ }
+
+ return 0;
+}
+
+/*==========================================
+ * #warp/#rura/#rura+ <mapname> <x> <y> <char name>
+ *------------------------------------------
+ */
+int charcommand_warp(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ char map_name[100];
+ char character[100];
+ int x = 0, y = 0;
+ struct map_session_data *pl_sd;
+ int m;
+
+ nullpo_retr(-1, sd);
+
+ memset(map_name, '\0', sizeof(map_name));
+ memset(character, '\0', sizeof(character));
+
+ if (!message || !*message || sscanf(message, "%99s %d %d %99[^\n]", map_name, &x, &y, character) < 4) {
+ clif_displaymessage(fd, "Usage: #warp/#rura/#rura+ <mapname> <x> <y> <char name>");
+ return -1;
+ }
+
+ if (x <= 0)
+ x = rand() % 399 + 1;
+ if (y <= 0)
+ y = rand() % 399 + 1;
+ if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat)
+ strcat(map_name, ".gat");
+
+ if ((pl_sd = map_nick2sd(character)) != NULL) {
+ if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can rura+ only lower or same GM level
+ if (x > 0 && x < 400 && y > 0 && y < 400) {
+ m = map_mapname2mapid(map_name);
+ if (m >= 0 && map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
+ clif_displaymessage(fd, "You are not authorised to warp someone to this map.");
+ return -1;
+ }
+ if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
+ clif_displaymessage(fd, "You are not authorised to warp this player from its actual map.");
+ return -1;
+ }
+ if (pc_setpos(pl_sd, map_name, x, y, 3) == 0) {
+ clif_displaymessage(pl_sd->fd, msg_table[0]); // Warped.
+ clif_displaymessage(fd, msg_table[15]); // Player warped (message sends to player too).
+ } else {
+ clif_displaymessage(fd, msg_table[1]); // Map not found.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[2]); // Coordinates out of range.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[81]); // Your GM level don't authorise you to do this action on this player.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[3]); // Character not found.
+ return -1;
+ }
+
+ return 0;
+}
+
+/*==========================================
+ * #zeny <charname>
+ *------------------------------------------
+ */
+int charcommand_zeny(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ struct map_session_data *pl_sd;
+ char character[100];
+ int zeny = 0, new_zeny;
+ nullpo_retr(-1, sd);
+
+ memset(character, '\0', sizeof(character));
+
+ if (!message || !*message || sscanf(message, "%d %99[^\n]", &zeny, character) < 2 || zeny == 0) {
+ clif_displaymessage(fd, "Please, enter a number and a player name (usage: #zeny <zeny> <name>).");
+ return -1;
+ }
+
+ if ((pl_sd = map_nick2sd(character)) != NULL) {
+ new_zeny = pl_sd->status.zeny + zeny;
+ if (zeny > 0 && (zeny > MAX_ZENY || new_zeny > MAX_ZENY)) // fix positiv overflow
+ new_zeny = MAX_ZENY;
+ else if (zeny < 0 && (zeny < -MAX_ZENY || new_zeny < 0)) // fix negativ overflow
+ new_zeny = 0;
+ if (new_zeny != pl_sd->status.zeny) {
+ pl_sd->status.zeny = new_zeny;
+ clif_updatestatus(pl_sd, SP_ZENY);
+ clif_displaymessage(fd, msg_table[211]); // Character's number of zenys changed!
+ } else {
+ if (zeny < 0)
+ clif_displaymessage(fd, msg_table[41]); // Impossible to decrease the number/value.
+ else
+ clif_displaymessage(fd, msg_table[149]); // Impossible to increase the number/value.
+ return -1;
+ }
+ } else {
+ clif_displaymessage(fd, msg_table[3]); // Character not found.
+ return -1;
+ }
+
+ return 0;
+}
+
+/*===================================
+ * Remove some messages
+ *-----------------------------------
+ */
+int charcommand_showexp(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ if (sd->noexp) {
+ sd->noexp = 0;
+ clif_displaymessage(fd, "Gained exp is now shown");
+ return 0;
+ }
+ else {
+ sd->noexp = 1;
+ clif_displaymessage(fd, "Gained exp is now NOT shown");
+ return 0;
+ }
+}
+
+int charcommand_showdelay(
+ const int fd, struct map_session_data* sd,
+ const char* command, const char* message)
+{
+ if (sd->nodelay) {
+ sd->nodelay = 0;
+ clif_displaymessage(fd, "Skill delay failure is now shown");
+ return 0;
+ }
+ else {
+ sd->nodelay = 1;
+ clif_displaymessage(fd, "Skill delay failure is NOT now shown");
+ return 0;
+ }
+}
+
diff --git a/src/map/charcommand.h b/src/map/charcommand.h
index 11babb816..7c1618cca 100644
--- a/src/map/charcommand.h
+++ b/src/map/charcommand.h
@@ -11,6 +11,15 @@ enum CharCommandType {
CharCommandOption,
CharCommandSave,
CharCommandStatsAll,
+ CharCommandSpiritball,
+ CharCommandItemList,
+ CharCommandEffect,
+ CharCommandStorageList,
+ CharCommandItem, // by MC Cameri
+ CharCommandWarp,
+ CharCommandZeny,
+ CharCommandShowDelay,
+ CharCommandShowExp,
#ifdef TXT_ONLY
/* TXT_ONLY */
diff --git a/src/map/chat.c b/src/map/chat.c
index 75788f03b..3bd29fec3 100644
--- a/src/map/chat.c
+++ b/src/map/chat.c
@@ -29,7 +29,7 @@ int chat_createchat(struct map_session_data *sd,int limit,int pub,char* pass,cha
nullpo_retr(0, sd);
- cd = aCalloc(1,sizeof(struct chat_data));
+ cd = (struct chat_data *) aCalloc(1,sizeof(struct chat_data));
cd->limit = limit;
cd->pub = pub;
@@ -49,7 +49,7 @@ int chat_createchat(struct map_session_data *sd,int limit,int pub,char* pass,cha
cd->bl.id = map_addobject(&cd->bl);
if(cd->bl.id==0){
clif_createchat(sd,1);
- free(cd);
+ aFree(cd);
return 0;
}
pc_setchatid(sd,cd->bl.id);
@@ -78,11 +78,11 @@ int chat_joinchat(struct map_session_data *sd,int chatid,char* pass)
clif_joinchatfail(sd,0);
return 0;
}
- if(cd->pub==0 && strncmp(pass,cd->pass,8)){
+ if(cd->pub==0 && strncmp(pass,(char *) cd->pass,8)){
clif_joinchatfail(sd,1);
return 0;
}
- if(chatid == sd->chatID) //Double Chat fix by Alex14, thx CHaNGeTe
+ if(chatid == (int)sd->chatID) //Double Chat fix by Alex14, thx CHaNGeTe
{
clif_joinchatfail(sd,1);
return 0;
@@ -268,14 +268,14 @@ int chat_createnpcchat(struct npc_data *nd,int limit,int pub,int trigger,char* t
nullpo_retr(1, nd);
- cd = aCalloc(1,sizeof(struct chat_data));
+ cd = (struct chat_data *) aCalloc(1,sizeof(struct chat_data));
cd->limit = cd->trigger = limit;
if(trigger>0)
cd->trigger = trigger;
cd->pub = pub;
cd->users = 0;
- memcpy(cd->pass,"",8);
+ memcpy(cd->pass,"",1);
if(titlelen>=sizeof(cd->title)-1) titlelen=sizeof(cd->title)-1;
memcpy(cd->title,title,titlelen);
cd->title[titlelen]=0;
@@ -286,11 +286,11 @@ int chat_createnpcchat(struct npc_data *nd,int limit,int pub,int trigger,char* t
cd->bl.type = BL_CHAT;
cd->owner_ = (struct block_list *)nd;
cd->owner = &cd->owner_;
- memcpy(cd->npc_event,ev,sizeof(cd->npc_event));
+ memcpy(cd->npc_event,ev,strlen(ev));
cd->bl.id = map_addobject(&cd->bl);
if(cd->bl.id==0){
- free(cd);
+ aFree(cd);
return 0;
}
nd->chat_id=cd->bl.id;
diff --git a/src/map/chrif.c b/src/map/chrif.c
index adb26868d..e250c8a18 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -23,6 +23,7 @@
#include "npc.h"
#include "pc.h"
#include "nullpo.h"
+#include "showmsg.h"
#ifdef MEMWATCH
#include "memwatch.h"
@@ -35,20 +36,22 @@ static const int packet_len_table[0x20] = {
-1,-1,10, 6,11,-1, 0, 0, // 2b10-2b17
};
-int char_fd;
+int chrif_connected;
+int char_fd = -1;
int srvinfo;
static char char_ip_str[16];
static int char_ip;
static int char_port = 6121;
static char userid[24], passwd[24];
-static int chrif_state;
+static int chrif_state = 0;
+static int char_init_done = 0;
// Ý’èƒtƒ@ƒCƒ‹“ǂݞ‚ÝŠÖŒW
/*==========================================
*
*------------------------------------------
*/
-void chrif_setuserid(char *id)
+void chrif_setuserid(char *id)
{
strncpy(userid, id, 24);
}
@@ -57,7 +60,7 @@ void chrif_setuserid(char *id)
*
*------------------------------------------
*/
-void chrif_setpasswd(char *pwd)
+void chrif_setpasswd(char *pwd)
{
strncpy(passwd, pwd, 24);
}
@@ -66,7 +69,7 @@ void chrif_setpasswd(char *pwd)
*
*------------------------------------------
*/
-void chrif_setip(char *ip)
+void chrif_setip(char *ip)
{
strncpy(char_ip_str, ip, 16);
char_ip = inet_addr(char_ip_str);
@@ -76,7 +79,7 @@ void chrif_setip(char *ip)
*
*------------------------------------------
*/
-void chrif_setport(int port)
+void chrif_setport(int port)
{
char_port = port;
}
@@ -85,7 +88,7 @@ void chrif_setport(int port)
*
*------------------------------------------
*/
-int chrif_isconnect(void)
+int chrif_isconnect(void)
{
return chrif_state == 2;
}
@@ -94,11 +97,11 @@ int chrif_isconnect(void)
*
*------------------------------------------
*/
-int chrif_save(struct map_session_data *sd)
+int chrif_save(struct map_session_data *sd)
{
nullpo_retr(-1, sd);
- if (char_fd < 0)
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
pc_makesavestatus(sd);
@@ -110,6 +113,8 @@ int chrif_save(struct map_session_data *sd)
memcpy(WFIFOP(char_fd,12), &sd->status, sizeof(sd->status));
WFIFOSET(char_fd, WFIFOW(char_fd,2));
+ storage_storage_save(sd); // to synchronise storage with character [Yor]
+
return 0;
}
@@ -117,7 +122,7 @@ int chrif_save(struct map_session_data *sd)
*
*------------------------------------------
*/
-int chrif_connect(int fd)
+int chrif_connect(int fd)
{
WFIFOW(fd,0) = 0x2af8;
memcpy(WFIFOP(fd,2), userid, 24);
@@ -134,13 +139,13 @@ int chrif_connect(int fd)
* ƒ}ƒbƒv‘—M
*------------------------------------------
*/
-int chrif_sendmap(int fd)
+int chrif_sendmap(int fd)
{
int i;
WFIFOW(fd,0) = 0x2afa;
for(i = 0; i < map_num; i++)
- if (map[i].alias[0] != '\0') // [MouseJstr] map aliasing
+ if (map[i].alias != '\0') // [MouseJstr] map aliasing
memcpy(WFIFOP(fd,4+i*16), map[i].alias, 16);
else
memcpy(WFIFOP(fd,4+i*16), map[i].name, 16);
@@ -165,7 +170,7 @@ int chrif_recvmap(int fd)
ip = RFIFOL(fd,4);
port = RFIFOW(fd,8);
for(i = 10, j = 0; i < RFIFOW(fd,2); i += 16, j++) {
- map_setipport(RFIFOP(fd,i), ip, port);
+ map_setipport((char*)RFIFOP(fd,i), ip, port);
// if (battle_config.etc_log)
// printf("recv map %d %s\n", j, RFIFOP(fd,i));
}
@@ -179,12 +184,15 @@ int chrif_recvmap(int fd)
* ƒ}ƒbƒvŽIŠÔˆÚ“®‚Ì‚½‚߂̃f[ƒ^€”õ—v‹
*------------------------------------------
*/
-int chrif_changemapserver(struct map_session_data *sd, char *name, int x, int y, int ip, short port)
+int chrif_changemapserver(struct map_session_data *sd, char *name, int x, int y, int ip, short port)
{
int i, s_ip;
nullpo_retr(-1, sd);
+ if( !sd || char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ return -1;
+
s_ip = 0;
for(i = 0; i < fd_max; i++)
if (session[i] && session[i]->session_data == sd) {
@@ -213,7 +221,7 @@ int chrif_changemapserver(struct map_session_data *sd, char *name, int x, int y,
* ƒ}ƒbƒvŽIŠÔˆÚ“®ack
*------------------------------------------
*/
-int chrif_changemapserverack(int fd)
+int chrif_changemapserverack(int fd)
{
struct map_session_data *sd = map_id2sd(RFIFOL(fd,2));
@@ -226,7 +234,7 @@ int chrif_changemapserverack(int fd)
pc_authfail(sd->fd);
return 0;
}
- clif_changemapserver(sd, RFIFOP(fd,18), RFIFOW(fd,34), RFIFOW(fd,36), RFIFOL(fd,38), RFIFOW(fd,42));
+ clif_changemapserver(sd, (char*)RFIFOP(fd,18), RFIFOW(fd,34), RFIFOW(fd,36), RFIFOL(fd,38), RFIFOW(fd,42));
return 0;
}
@@ -235,19 +243,28 @@ int chrif_changemapserverack(int fd)
*
*------------------------------------------
*/
-int chrif_connectack(int fd)
+int chrif_connectack(int fd)
{
if (RFIFOB(fd,2)) {
printf("Connected to char-server failed %d.\n", RFIFOB(fd,2));
exit(1);
}
- printf("Connected to char-server (connection #%d).\n", fd);
+ sprintf(tmp_output,"Successfully connected to Char Server (Connection: '"CL_WHITE"%d"CL_RESET"').\n",fd);
+ ShowStatus(tmp_output);
chrif_state = 1;
+ chrif_connected=1;
chrif_sendmap(fd);
- printf("chrif: OnCharIfInit event done. (%d events)\n", npc_event_doall("OnCharIfInit"));
- printf("chrif: OnInterIfInit event done. (%d events)\n", npc_event_doall("OnInterIfInit"));
+ sprintf(tmp_output,"Event '"CL_WHITE"OnCharIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnCharIfInit"));
+ ShowStatus(tmp_output);
+ sprintf(tmp_output,"Event '"CL_WHITE"OnInterIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnInterIfInit"));
+ ShowStatus(tmp_output);
+ if(!char_init_done) {
+ char_init_done = 1;
+ sprintf(tmp_output,"Event '"CL_WHITE"OnInterIfInitOnce"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnInterIfInitOnce"));
+ ShowStatus(tmp_output);
+ }
// <Agit> Run Event [AgitInit]
// printf("NPC_Event:[OnAgitInit] do (%d) events (Agit Initialize).\n", npc_event_doall("OnAgitInit"));
@@ -259,7 +276,7 @@ int chrif_connectack(int fd)
*
*------------------------------------------
*/
-int chrif_sendmapack(int fd)
+int chrif_sendmapack(int fd)
{
if (RFIFOB(fd,2)) {
printf("chrif : send map list to char server failed %d\n", RFIFOB(fd,2));
@@ -277,13 +294,15 @@ int chrif_sendmapack(int fd)
*
*------------------------------------------
*/
-int chrif_authreq(struct map_session_data *sd)
+int chrif_authreq(struct map_session_data *sd)
{
int i;
nullpo_retr(-1, sd);
- if (!sd || !char_fd || !sd->bl.id || !sd->login_id1)
+ if(!sd || !sd->bl.id || !sd->login_id1)
+ return -1;
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
for(i = 0; i < fd_max; i++)
@@ -305,13 +324,15 @@ int chrif_authreq(struct map_session_data *sd)
*
*------------------------------------------
*/
-int chrif_charselectreq(struct map_session_data *sd)
+int chrif_charselectreq(struct map_session_data *sd)
{
int i, s_ip;
nullpo_retr(-1, sd);
- if(!sd || !char_fd || !sd->bl.id || !sd->login_id1)
+ if( !sd || !sd->bl.id || !sd->login_id1 )
+ return -1;
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
s_ip = 0;
@@ -335,9 +356,11 @@ int chrif_charselectreq(struct map_session_data *sd)
* ƒLƒƒƒ‰–¼–â‚¢‡‚킹
*------------------------------------------
*/
-int chrif_searchcharid(int char_id)
+int chrif_searchcharid(int char_id)
{
- if (!char_id)
+ if( !char_id )
+ return -1;
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
WFIFOW(char_fd,0) = 0x2b08;
@@ -351,11 +374,14 @@ int chrif_searchcharid(int char_id)
* GM‚ɕω»—v‹
*------------------------------------------
*/
-int chrif_changegm(int id, const char *pass, int len)
+int chrif_changegm(int id, const char *pass, int len)
{
if (battle_config.etc_log)
printf("chrif_changegm: account: %d, password: '%s'.\n", id, pass);
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ return -1;
+
WFIFOW(char_fd,0) = 0x2b0a;
WFIFOW(char_fd,2) = len + 8;
WFIFOL(char_fd,4) = id;
@@ -369,11 +395,14 @@ int chrif_changegm(int id, const char *pass, int len)
* Change Email
*------------------------------------------
*/
-int chrif_changeemail(int id, const char *actual_email, const char *new_email)
+int chrif_changeemail(int id, const char *actual_email, const char *new_email)
{
if (battle_config.etc_log)
printf("chrif_changeemail: account: %d, actual_email: '%s', new_email: '%s'.\n", id, actual_email, new_email);
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ return -1;
+
WFIFOW(char_fd,0) = 0x2b0c;
WFIFOL(char_fd,2) = id;
memcpy(WFIFOP(char_fd,6), actual_email, 40);
@@ -394,8 +423,11 @@ int chrif_changeemail(int id, const char *actual_email, const char *new_email)
* 5: changesex
*------------------------------------------
*/
-int chrif_char_ask_name(int id, char * character_name, short operation_type, int year, int month, int day, int hour, int minute, int second)
+int chrif_char_ask_name(int id, char * character_name, short operation_type, int year, int month, int day, int hour, int minute, int second)
{
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ return -1;
+
WFIFOW(char_fd, 0) = 0x2b0e;
WFIFOL(char_fd, 2) = id; // account_id of who ask (for answer) -1 if nobody
memcpy(WFIFOP(char_fd,6), character_name, 24);
@@ -419,7 +451,10 @@ int chrif_char_ask_name(int id, char * character_name, short operation_type, int
*------------------------------------------
*/
int chrif_changesex(int id, int sex) {
- WFIFOW(char_fd,0) = 0x3000;
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ return -1;
+
+ WFIFOW(char_fd,0) = 0x2b11;
WFIFOW(char_fd,2) = 9;
WFIFOL(char_fd,4) = id;
WFIFOB(char_fd,8) = sex;
@@ -444,7 +479,7 @@ int chrif_changesex(int id, int sex) {
* 3: login-server offline
*------------------------------------------
*/
-int chrif_char_ask_name_answer(int fd)
+int chrif_char_ask_name_answer(int fd)
{
int acc;
struct map_session_data *sd;
@@ -547,7 +582,7 @@ int chrif_char_ask_name_answer(int fd)
* End of GM change (@GM) (modified by Yor)
*------------------------------------------
*/
-int chrif_changedgm(int fd)
+int chrif_changedgm(int fd)
{
int acc, level;
struct map_session_data *sd = NULL;
@@ -573,7 +608,7 @@ int chrif_changedgm(int fd)
* «•ʕω»I—¹ (modified by Yor)
*------------------------------------------
*/
-int chrif_changedsex(int fd)
+int chrif_changedsex(int fd)
{
int acc, sex, i;
struct map_session_data *sd;
@@ -586,7 +621,7 @@ int chrif_changedsex(int fd)
sd = map_id2sd(acc);
if (acc > 0) {
if (sd != NULL && sd->status.sex != sex) {
- s_class = pc_calc_base_job(sd->status.class);
+ s_class = pc_calc_base_job(sd->status.class_);
if (sd->status.sex == 0) {
sd->status.sex = 1;
sd->sex = 1;
@@ -597,7 +632,7 @@ int chrif_changedsex(int fd)
// to avoid any problem with equipment and invalid sex, equipment is unequiped.
for (i = 0; i < MAX_INVENTORY; i++) {
if (sd->status.inventory[i].nameid && sd->status.inventory[i].equip)
- pc_unequipitem((struct map_session_data*)sd, i, 0, BF_NORMAL);
+ pc_unequipitem((struct map_session_data*)sd, i, 2);
}
// reset skill of some job
if (s_class.job == 19 || s_class.job == 4020 || s_class.job == 4042 ||
@@ -621,15 +656,15 @@ int chrif_changedsex(int fd)
clif_updatestatus(sd, SP_SKILLPOINT);
// change job if necessary
if (s_class.job == 20 || s_class.job == 4021 || s_class.job == 4043)
- sd->status.class -= 1;
+ sd->status.class_ -= 1;
else if (s_class.job == 19 || s_class.job == 4020 || s_class.job == 4042)
- sd->status.class += 1;
+ sd->status.class_ += 1;
}
// save character
chrif_save(sd);
sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters
// do same modify in login-server for the account, but no in char-server (it ask again login_id1 to login, and don't remember it)
- clif_displaymessage(sd->fd, "Your sex has been changed (need disconexion by the server)...");
+ clif_displaymessage(sd->fd, "Your sex has been changed (need disconnection by the server)...");
clif_setwaitclose(sd->fd); // forced to disconnect for the change
}
} else {
@@ -645,11 +680,14 @@ int chrif_changedsex(int fd)
* ƒAƒJƒEƒ“ƒg•Ï”•Û‘¶—v‹
*------------------------------------------
*/
-int chrif_saveaccountreg2(struct map_session_data *sd)
+int chrif_saveaccountreg2(struct map_session_data *sd)
{
int p, j;
nullpo_retr(-1, sd);
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ return -1;
+
p = 8;
for(j = 0; j < sd->status.account_reg2_num; j++) {
struct global_reg *reg = &sd->status.account_reg2[j];
@@ -671,7 +709,7 @@ int chrif_saveaccountreg2(struct map_session_data *sd)
* ƒAƒJƒEƒ“ƒg•Ï”’Ê’m
*------------------------------------------
*/
-int chrif_accountreg2(int fd)
+int chrif_accountreg2(int fd)
{
int j, p;
struct map_session_data *sd;
@@ -693,7 +731,7 @@ int chrif_accountreg2(int fd)
* —£¥î•ñ“¯Šú—v‹
*------------------------------------------
*/
-int chrif_divorce(int char_id, int partner_id)
+int chrif_divorce(int char_id, int partner_id)
{
struct map_session_data *sd = NULL;
@@ -719,7 +757,7 @@ int chrif_divorce(int char_id, int partner_id)
* Disconnection of a player (account has been deleted in login-server) by [Yor]
*------------------------------------------
*/
-int chrif_accountdeletion(int fd)
+int chrif_accountdeletion(int fd)
{
int acc;
struct map_session_data *sd;
@@ -731,7 +769,7 @@ int chrif_accountdeletion(int fd)
if (acc > 0) {
if (sd != NULL) {
sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters
- clif_displaymessage(sd->fd, "Your account has been deleted (disconnexion)...");
+ clif_displaymessage(sd->fd, "Your account has been deleted (disconnection)...");
clif_setwaitclose(sd->fd); // forced to disconnect for the change
}
} else {
@@ -746,7 +784,7 @@ int chrif_accountdeletion(int fd)
* Disconnection of a player (account has been banned of has a status, from login-server) by [Yor]
*------------------------------------------
*/
-int chrif_accountban(int fd)
+int chrif_accountban(int fd)
{
int acc;
struct map_session_data *sd;
@@ -820,7 +858,7 @@ int chrif_chardisconnect(struct map_session_data *sd)
{
nullpo_retr(-1, sd);
- if(char_fd<=0)
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
WFIFOW(char_fd,0)=0x2b18;
@@ -836,10 +874,11 @@ int chrif_chardisconnect(struct map_session_data *sd)
* Receiving GM accounts and their levels from char-server by [Yor]
*------------------------------------------
*/
-int chrif_recvgmaccounts(int fd)
+int chrif_recvgmaccounts(int fd)
{
- printf("From login-server: receiving of %d GM accounts information.\n", pc_read_gm_account(fd));
-
+ sprintf(tmp_output,"From login-server: receiving information of '"CL_WHITE"%d"CL_RESET"' GM accounts.\n", pc_read_gm_account(fd));
+ ShowInfo(tmp_output);
+ memset(tmp_output,'\0',sizeof(tmp_output));
return 0;
}
@@ -847,8 +886,10 @@ int chrif_recvgmaccounts(int fd)
* Request to reload GM accounts and their levels: send to char-server by [Yor]
*------------------------------------------
*/
-int chrif_reloadGMdb(void)
+int chrif_reloadGMdb(void)
{
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ return -1;
WFIFOW(char_fd,0) = 0x2af7;
WFIFOSET(char_fd, 2);
@@ -860,12 +901,15 @@ int chrif_reloadGMdb(void)
* Send rates and motd to char server [Wizputer]
*------------------------------------------
*/
- int chrif_ragsrvinfo(int base_rate, int job_rate, int drop_rate)
+ int chrif_ragsrvinfo(int base_rate, int job_rate, int drop_rate)
{
char buf[256];
FILE *fp;
int i;
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ return -1;
+
WFIFOW(char_fd,0) = 0x2b16;
WFIFOW(char_fd,2) = base_rate;
WFIFOW(char_fd,4) = job_rate;
@@ -897,14 +941,62 @@ int chrif_reloadGMdb(void)
*-----------------------------------------
*/
-int chrif_char_offline(struct map_session_data *sd)
+int chrif_char_offline(struct map_session_data *sd)
{
- if (char_fd < 0)
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
WFIFOW(char_fd,0) = 0x2b17;
WFIFOL(char_fd,2) = sd->status.char_id;
- WFIFOSET(char_fd,6);
+ WFIFOL(char_fd,6) = sd->status.account_id;
+ WFIFOSET(char_fd,10);
+
+ return 0;
+}
+
+/*=========================================
+ * Tell char-server to reset all chars offline [Wizputer]
+ *-----------------------------------------
+ */
+int chrif_flush_fifo(void) {
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ return -1;
+
+ set_nonblocking(char_fd, 0);
+ flush_fifos();
+ set_nonblocking(char_fd, 1);
+
+ return 0;
+}
+
+/*=========================================
+ * Tell char-server to reset all chars offline [Wizputer]
+ *-----------------------------------------
+ */
+int chrif_char_reset_offline(void) {
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ return -1;
+
+ WFIFOW(char_fd,0) = 0x2b18;
+ WFIFOSET(char_fd,2);
+
+ return 0;
+}
+
+/*=========================================
+ * Tell char-server charcter is online [Wizputer]
+ *-----------------------------------------
+ */
+
+int chrif_char_online(struct map_session_data *sd)
+{
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ return -1;
+
+ WFIFOW(char_fd,0) = 0x2b19;
+ WFIFOL(char_fd,2) = sd->status.char_id;
+ WFIFOL(char_fd,6) = sd->status.account_id;
+ WFIFOSET(char_fd,10);
return 0;
}
@@ -913,16 +1005,39 @@ int chrif_char_offline(struct map_session_data *sd)
*
*------------------------------------------
*/
-int chrif_parse(int fd)
+int chrif_disconnect_sub(struct map_session_data* sd,va_list va) {
+ clif_authfail_fd(sd->fd,1);
+ map_quit(sd);
+ return 0;
+}
+
+int chrif_disconnect(int fd) {
+ if(fd == char_fd) {
+ char_fd = 0;
+ sprintf(tmp_output,"Map Server disconnected from Char Server.\n\n");
+ ShowWarning(tmp_output);
+ clif_foreachclient(chrif_disconnect_sub);
+ chrif_connected = 0;
+ // ‘¼‚Ìmap ŽI‚̃f[ƒ^‚ðÁ‚·
+ map_eraseallipport();
+ }
+ close(fd);
+ return 0;
+}
+
+/*==========================================
+ *
+ *------------------------------------------
+ */
+int chrif_parse(int fd)
{
int packet_len, cmd;
-
// only char-server can have an access to here.
// so, if it isn't the char-server, we disconnect the session (fd != char_fd).
if (fd != char_fd || session[fd]->eof) {
- if (fd == char_fd) {
- printf("Map-server can't connect to char-server (connection #%d).\n", fd);
- char_fd = -1;
+ if (fd == char_fd && chrif_connected == 1) {
+ chrif_disconnect (fd);
+// check_connect_char_server(0, 0, 0, 0);
}
close(fd);
delete_session(fd);
@@ -956,11 +1071,11 @@ int chrif_parse(int fd)
case 0x2afb: chrif_sendmapack(fd); break;
case 0x2afd: pc_authok(RFIFOL(fd,4), RFIFOL(fd,8), (time_t)RFIFOL(fd,12), (struct mmo_charstatus*)RFIFOP(fd,16)); break;
case 0x2afe: pc_authfail(RFIFOL(fd,2)); break;
- case 0x2b00: map_setusers(RFIFOL(fd,2)); break;
+ case 0x2b00: map_setusers(fd); break;
case 0x2b03: clif_charselectok(RFIFOL(fd,2)); break;
case 0x2b04: chrif_recvmap(fd); break;
case 0x2b06: chrif_changemapserverack(fd); break;
- case 0x2b09: map_addchariddb(RFIFOL(fd,2), RFIFOP(fd,6)); break;
+ case 0x2b09: map_addchariddb(RFIFOL(fd,2), (char*)RFIFOP(fd,6)); break;
case 0x2b0b: chrif_changedgm(fd); break;
case 0x2b0d: chrif_changedsex(fd); break;
case 0x2b0f: chrif_char_ask_name_answer(fd); break;
@@ -991,12 +1106,12 @@ int send_users_tochar(int tid, unsigned int tick, int id, int data) {
int users = 0, i;
struct map_session_data *sd;
- if (char_fd <= 0 || session[char_fd] == NULL)
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) // Thanks to Toster
return 0;
WFIFOW(char_fd,0) = 0x2aff;
for (i = 0; i < fd_max; i++) {
- if (session[i] && (sd = session[i]->session_data) && sd->state.auth &&
+ if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) && sd->state.auth &&
!((battle_config.hide_GM_session || (sd->status.option & OPTION_HIDE)) && pc_isGM(sd))) {
WFIFOL(char_fd,6+4*users) = sd->status.char_id;
users++;
@@ -1015,14 +1130,19 @@ int send_users_tochar(int tid, unsigned int tick, int id, int data) {
*------------------------------------------
*/
int check_connect_char_server(int tid, unsigned int tick, int id, int data) {
+ static int displayed = 0;
if (char_fd <= 0 || session[char_fd] == NULL) {
- printf("Attempt to connect to char-server...\n");
+ if (!displayed) {
+ ShowStatus("Attempting to connect to Char Server. Please wait.\n");
+ displayed = 1;
+ }
chrif_state = 0;
char_fd = make_connection(char_ip, char_port);
session[char_fd]->func_parse = chrif_parse;
realloc_fifo(char_fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
chrif_connect(char_fd);
+ chrif_connected = chrif_isconnect();
#ifndef TXT_ONLY
srvinfo = 0;
} else {
@@ -1032,7 +1152,16 @@ int check_connect_char_server(int tid, unsigned int tick, int id, int data) {
}
#endif /* not TXT_ONLY */
}
-
+ if (chrif_isconnect()) displayed = 0;
+ return 0;
+}
+/*==========================================
+ * I—¹
+ *------------------------------------------
+ */
+int do_final_chrif(void)
+{
+ delete_session(char_fd);
return 0;
}
diff --git a/src/map/chrif.h b/src/map/chrif.h
index de20c3086..f2b258ea9 100644
--- a/src/map/chrif.h
+++ b/src/map/chrif.h
@@ -9,6 +9,8 @@ void chrif_setport(int);
int chrif_isconnect(void);
+extern int chrif_connected;
+
int chrif_authreq(struct map_session_data *);
int chrif_save(struct map_session_data*);
int chrif_charselectreq(struct map_session_data *);
@@ -23,9 +25,15 @@ int chrif_saveaccountreg2(struct map_session_data *sd);
int chrif_reloadGMdb(void);
int chrif_ragsrvinfo(int base_rate,int job_rate, int drop_rate);
int chrif_char_offline(struct map_session_data *sd);
+int chrif_char_reset_offline(void);
+int chrif_char_online(struct map_session_data *sd);
int chrif_changesex(int id, int sex);
int chrif_chardisconnect(struct map_session_data *sd);
+int check_connect_char_server(int tid, unsigned int tick, int id, int data);
+int do_final_chrif(void);
int do_init_chrif(void);
+int chrif_flush_fifo(void);
+
#endif
diff --git a/src/map/clif.c b/src/map/clif.c
index 9163671a8..c8f190c5a 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -1,6 +1,7 @@
// $Id: clif.c 2200 2004-11-07 11:49:58Z Yor $
#define DUMP_UNKNOWN_PACKET 1
+#define DUMP_ALL_PACKETS 0
#include <stdio.h>
#include <ctype.h>
@@ -24,11 +25,13 @@
#include "../common/malloc.h"
#include "../common/version.h"
#include "../common/nullpo.h"
+#include "../common/showmsg.h"
#include "map.h"
#include "chrif.h"
#include "clif.h"
#include "pc.h"
+#include "status.h"
#include "npc.h"
#include "itemdb.h"
#include "chat.h"
@@ -52,7 +55,16 @@
#define STATE_BLIND 0x10
-static const int packet_len_table[0x220] = {
+struct Clif_Config clif_config;
+struct packet_db packet_db[MAX_PACKET_VER + 1][MAX_PACKET_DB];
+
+#define USE_PACKET_DB(sd) \
+ clif_config.enable_packet_db && sd->packet_ver == clif_config.packet_db_ver
+
+#define IS_PACKET_DB_VER(cmd) \
+ cmd == clif_config.connect_cmd
+
+static const int packet_len_table[MAX_PACKET_DB] = {
10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -67,12 +79,12 @@ static const int packet_len_table[0x220] = {
3, 28, 19, 11, 3, -1, 9, 5, 54, 53, 58, 60, 41, 2, 6, 6,
#endif
//#0x0080
- 7, 3, 2, 2, 2, 5, 16, 12, 10, 7, 29, 23, -1, -1, -1, 0, // 0x8b unknown... size 2 or 23?
+ 7, 3, 2, 2, 2, 5, 16, 12, 10, 7, 29, 2, -1, -1, -1, 0, // 0x8b changed to 2 (was 23)
7, 22, 28, 2, 6, 30, -1, -1, 3, -1, -1, 5, 9, 17, 17, 6,
23, 6, 6, -1, -1, -1, -1, 8, 7, 6, 7, 4, 7, 0, -1, 6,
8, 8, 3, 3, -1, 6, 6, -1, 7, 6, 2, 5, 6, 44, 5, 3,
//#0x00C0
- 7, 2, 6, 8, 6, 7, -1, -1, -1, -1, 3, 3, 6, 6, 2, 27,
+ 7, 2, 6, 8, 6, 7, -1, -1, -1, -1, 3, 3, 6, 3, 2, 27, // 0xcd change to 3 (was 6)
3, 4, 4, 2, -1, -1, 3, -1, 6, 14, 3, -1, 28, 29, -1, -1,
30, 30, 26, 2, 6, 26, 3, 3, 8, 19, 5, 2, 3, 2, 2, 2,
3, 2, 6, 8, 21, 8, 8, 2, 2, 26, 3, -1, 6, 27, 30, 10,
@@ -102,13 +114,11 @@ static const int packet_len_table[0x220] = {
30, 8, 34, 14, 2, 6, 26, 2, 28, 81, 6, 10, 26, 2, -1, -1,
-1, -1, 20, 10, 32, 9, 34, 14, 2, 6, 48, 56, -1, 4, 5, 10,
//#0x200
- 26, -1, 26, 10, 18, 26, 11, 34, 14, 36, 10, 19, 0, -1, 24, 0,
+ 26, -1, 26, 10, 18, 26, 11, 34, 14, 36, 10, 0, 0, -1, 24, 0, // 0x20c change to 0 (was 19)
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
};
-// size list for each packet version after packet version 4.
-static int packet_size_table[9][0x220];
-
// local define
enum {
ALL_CLIENT,
@@ -143,6 +153,7 @@ enum {
static char map_ip_str[16];
static in_addr_t map_ip;
+static in_addr_t bind_ip = INADDR_ANY;
static int map_port = 5121;
int map_fd;
char talkie_mes[80];
@@ -151,17 +162,22 @@ char talkie_mes[80];
* mapŽI‚ÌipÝ’è
*------------------------------------------
*/
-void clif_setip(char *ip)
+void clif_setip(char *ip)
{
memcpy(map_ip_str, ip, 16);
map_ip = inet_addr(map_ip_str);
}
+void clif_setbindip(char *ip)
+{
+ bind_ip = inet_addr(ip);
+}
+
/*==========================================
* mapŽI‚ÌportÝ’è
*------------------------------------------
*/
-void clif_setport(int port)
+void clif_setport(int port)
{
map_port = port;
}
@@ -170,7 +186,7 @@ void clif_setport(int port)
* mapŽI‚Ìip“Ç‚Ýo‚µ
*------------------------------------------
*/
-in_addr_t clif_getip(void)
+in_addr_t clif_getip(void)
{
return map_ip;
}
@@ -179,7 +195,7 @@ in_addr_t clif_getip(void)
* mapŽI‚Ìport“Ç‚Ýo‚µ
*------------------------------------------
*/
-int clif_getport(void)
+int clif_getport(void)
{
return map_port;
}
@@ -188,13 +204,13 @@ int clif_getport(void)
*
*------------------------------------------
*/
-int clif_countusers(void)
+int clif_countusers(void)
{
int users = 0, i;
struct map_session_data *sd;
for(i = 0; i < fd_max; i++) {
- if (session[i] && (sd = session[i]->session_data) && sd && sd->state.auth &&
+ if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) && sd && sd->state.auth &&
!(battle_config.hide_GM_session && pc_isGM(sd)))
users++;
}
@@ -205,7 +221,7 @@ int clif_countusers(void)
* ‘S‚Ä‚Ìclient‚ɑ΂µ‚Äfunc()ŽÀs
*------------------------------------------
*/
-int clif_foreachclient(int (*func)(struct map_session_data*, va_list),...)
+int clif_foreachclient(int (*func)(struct map_session_data*, va_list),...)
{
int i;
va_list ap;
@@ -213,7 +229,7 @@ int clif_foreachclient(int (*func)(struct map_session_data*, va_list),...)
va_start(ap,func);
for(i = 0; i < fd_max; i++) {
- if (session[i] && (sd = session[i]->session_data) && sd && sd->state.auth)
+ if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) && sd && sd->state.auth)
func(sd, ap);
}
va_end(ap);
@@ -224,14 +240,13 @@ int clif_foreachclient(int (*func)(struct map_session_data*, va_list),...)
* clif_send‚ÅAREA*Žw’莞—p
*------------------------------------------
*/
-int clif_send_sub(struct block_list *bl, va_list ap)
+int clif_send_sub(struct block_list *bl, va_list ap)
{
- unsigned char *buf;
- int len;
struct block_list *src_bl;
- int type;
struct map_session_data *sd;
-
+ unsigned char *buf;
+ int len, type;
+
nullpo_retr(0, bl);
nullpo_retr(0, ap);
nullpo_retr(0, sd = (struct map_session_data *)bl);
@@ -243,27 +258,30 @@ int clif_send_sub(struct block_list *bl, va_list ap)
switch(type) {
case AREA_WOS:
- if (bl && bl == src_bl)
+ if (bl == src_bl)
return 0;
break;
case AREA_WOC:
- if ((sd && sd->chatID) || (bl && bl == src_bl))
+ if (sd->chatID || bl == src_bl)
return 0;
break;
case AREA_WOSC:
- if ((sd) && sd->chatID && sd->chatID == ((struct map_session_data*)src_bl)->chatID)
- return 0;
+ {
+ struct map_session_data *ssd = (struct map_session_data *)src_bl;
+ if (ssd && sd->chatID && sd->chatID == ssd->chatID)
+ return 0;
+ }
break;
}
- if (sd) {
+ if (session[sd->fd] != NULL) {
if (WFIFOP(sd->fd,0) == buf) {
printf("WARNING: Invalid use of clif_send function\n");
printf(" Packet x%4x use a WFIFO of a player instead of to use a buffer.\n", WBUFW(buf,0));
printf(" Please correct your code.\n");
// don't send to not move the pointer of the packet for next sessions in the loop
} else {
- if (packet_size_table[sd->packet_ver-5][RBUFW(buf,0)]) { // packet must exist for the client version
+ if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
memcpy(WFIFOP(sd->fd,0), buf, len);
WFIFOSET(sd->fd,len);
}
@@ -279,8 +297,7 @@ int clif_send_sub(struct block_list *bl, va_list ap)
*/
int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
int i;
- struct map_session_data *sd;
- struct chat_data *cd;
+ struct map_session_data *sd = NULL;
struct party *p = NULL;
struct guild *g = NULL;
int x0 = 0, x1 = 0, y0 = 0, y1 = 0;
@@ -288,12 +305,15 @@ int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
if (type != ALL_CLIENT) {
nullpo_retr(0, bl);
}
+ if (bl && bl->type == BL_PC) {
+ nullpo_retr (0, sd=(struct map_session_data*)bl);
+ }
switch(type) {
case ALL_CLIENT: // ‘SƒNƒ‰ƒCƒAƒ“ƒg‚É‘—M
for(i = 0; i < fd_max; i++) {
- if (session[i] && (sd = session[i]->session_data) != NULL && sd->state.auth) {
- if (packet_size_table[sd->packet_ver-5][RBUFW(buf,0)]) { // packet must exist for the client version
+ if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL && sd->state.auth) {
+ if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
memcpy(WFIFOP(i,0), buf, len);
WFIFOSET(i,len);
}
@@ -302,8 +322,8 @@ int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
break;
case ALL_SAMEMAP: // “¯‚¶ƒ}ƒbƒv‚Ì‘SƒNƒ‰ƒCƒAƒ“ƒg‚É‘—M
for(i = 0; i < fd_max; i++) {
- if (session[i] && (sd = session[i]->session_data) != NULL && sd->state.auth && sd->bl.m == bl->m) {
- if (packet_size_table[sd->packet_ver-5][RBUFW(buf,0)]) { // packet must exist for the client version
+ if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL && sd->state.auth && sd->bl.m == bl->m) {
+ if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
memcpy(WFIFOP(i,0), buf, len);
WFIFOSET(i,len);
}
@@ -321,21 +341,24 @@ int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
break;
case CHAT:
case CHAT_WOS:
- cd = (struct chat_data*)bl;
- if (bl->type == BL_PC) {
- sd = (struct map_session_data*)bl;
- cd = (struct chat_data*)map_id2bl(sd->chatID);
- } else if (bl->type != BL_CHAT)
- break;
- if (cd == NULL)
- break;
- for(i = 0; i < cd->users; i++) {
- if (type == CHAT_WOS && cd->usersd[i] == (struct map_session_data*)bl)
- continue;
- if (packet_size_table[cd->usersd[i]->packet_ver-5][RBUFW(buf,0)]) { // packet must exist for the client version
- if (cd->usersd[i]->fd >=0 && session[cd->usersd[i]->fd]) // Added check to see if session exists [PoW]
- memcpy(WFIFOP(cd->usersd[i]->fd,0), buf, len);
- WFIFOSET(cd->usersd[i]->fd,len);
+ {
+ struct chat_data *cd;
+ if (sd) {
+ cd = (struct chat_data*)map_id2bl(sd->chatID);
+ } else if (bl->type == BL_CHAT) {
+ cd = (struct chat_data*)bl;
+ } else if (bl->type != BL_CHAT)
+ break;
+ if (cd == NULL)
+ break;
+ for(i = 0; i < cd->users; i++) {
+ if (type == CHAT_WOS && cd->usersd[i] == sd)
+ continue;
+ if (packet_db[cd->usersd[i]->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
+ if (cd->usersd[i]->fd >=0 && session[cd->usersd[i]->fd]) // Added check to see if session exists [PoW]
+ memcpy(WFIFOP(cd->usersd[i]->fd,0), buf, len);
+ WFIFOSET(cd->usersd[i]->fd,len);
+ }
}
}
break;
@@ -350,18 +373,18 @@ int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
case PARTY_WOS: // Ž©•ªˆÈŠO‚Ì‘Sƒp[ƒeƒB[ƒƒ“ƒo‚É‘—M
case PARTY_SAMEMAP: // “¯‚¶ƒ}ƒbƒv‚Ì‘Sƒp[ƒeƒB[ƒƒ“ƒo‚É‘—M
case PARTY_SAMEMAP_WOS: // Ž©•ªˆÈŠO‚Ì“¯‚¶ƒ}ƒbƒv‚Ì‘Sƒp[ƒeƒB[ƒƒ“ƒo‚É‘—M
- if (bl->type == BL_PC) {
- sd = (struct map_session_data *)bl;
+ if (sd) {
if (sd->partyspy > 0) {
p = party_search(sd->partyspy);
- } else {
- if (sd->status.party_id > 0)
- p = party_search(sd->status.party_id);
+ } else if (sd->status.party_id > 0) {
+ p = party_search(sd->status.party_id);
}
}
if (p) {
for(i=0;i<MAX_PARTY;i++){
if ((sd = p->member[i].sd) != NULL) {
+ if ((session[sd->fd] == NULL) || (session[sd->fd]->session_data == NULL))
+ continue;
if (sd->bl.id == bl->id && (type == PARTY_WOS ||
type == PARTY_SAMEMAP_WOS || type == PARTY_AREA_WOS))
continue;
@@ -371,7 +394,7 @@ int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
(sd->bl.x < x0 || sd->bl.y < y0 ||
sd->bl.x > x1 || sd->bl.y > y1))
continue;
- if (packet_size_table[sd->packet_ver-5][RBUFW(buf,0)]) { // packet must exist for the client version
+ if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
memcpy(WFIFOP(sd->fd,0), buf, len);
WFIFOSET(sd->fd,len);
}
@@ -381,9 +404,9 @@ int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
}
}
for (i = 0; i < fd_max; i++){
- if (session[i] && (sd = session[i]->session_data) != NULL && sd->state.auth) {
+ if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL && sd->state.auth) {
if (sd->partyspy == p->party_id) {
- if (packet_size_table[sd->packet_ver-5][RBUFW(buf,0)]) { // packet must exist for the client version
+ if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
memcpy(WFIFOP(sd->fd,0), buf, len);
WFIFOSET(sd->fd,len);
}
@@ -393,8 +416,7 @@ int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
}
break;
case SELF:
- sd = (struct map_session_data *)bl;
- if (packet_size_table[sd->packet_ver-5][RBUFW(buf,0)]) { // packet must exist for the client version
+ if (sd && packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
memcpy(WFIFOP(sd->fd,0), buf, len);
WFIFOSET(sd->fd,len);
}
@@ -410,13 +432,11 @@ int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
y1 = bl->y + AREA_SIZE;
case GUILD:
case GUILD_WOS:
- if (bl && bl->type == BL_PC) { // guildspy [Syrus22]
- sd = (struct map_session_data *)bl;
+ if (sd) { // guildspy [Syrus22]
if (sd->guildspy > 0) {
g = guild_search(sd->guildspy);
- } else {
- if (sd->status.guild_id > 0)
- g = guild_search(sd->status.guild_id);
+ } else if (sd->status.guild_id > 0) {
+ g = guild_search(sd->status.guild_id);
}
}
if (g) {
@@ -424,16 +444,18 @@ int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
if ((sd = g->member[i].sd) != NULL) {
if (type == GUILD_WOS && sd->bl.id == bl->id)
continue;
- if (packet_size_table[sd->packet_ver-5][RBUFW(buf,0)]) { // packet must exist for the client version
+ if (sd->packet_ver > MAX_PACKET_VER)
+ continue;
+ if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
memcpy(WFIFOP(sd->fd,0), buf, len);
WFIFOSET(sd->fd,len);
}
}
}
for (i = 0; i < fd_max; i++){
- if (session[i] && (sd = session[i]->session_data) != NULL && sd->state.auth) {
+ if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL && sd->state.auth) {
if (sd->guildspy == g->guild_id) {
- if (packet_size_table[sd->packet_ver-5][RBUFW(buf,0)]) { // packet must exist for the client version
+ if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
memcpy(WFIFOP(sd->fd,0), buf, len);
WFIFOSET(sd->fd,len);
}
@@ -444,10 +466,8 @@ int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
break;
case GUILD_SAMEMAP:
case GUILD_SAMEMAP_WOS:
- if (bl->type == BL_PC) {
- sd = (struct map_session_data *)bl;
- if (sd->status.guild_id > 0)
- g = guild_search(sd->status.guild_id);
+ if (sd && sd->status.guild_id > 0) {
+ g = guild_search(sd->status.guild_id);
}
if (g) {
for(i = 0; i < g->max_member; i++) {
@@ -461,7 +481,7 @@ int clif_send(unsigned char *buf, int len, struct block_list *bl, int type) {
(sd->bl.x < x0 || sd->bl.y < y0 ||
sd->bl.x > x1 || sd->bl.y > y1))
continue;
- if (packet_size_table[sd->packet_ver-5][RBUFW(buf,0)]) { // packet must exist for the client version
+ if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
memcpy(WFIFOP(sd->fd,0), buf, len);
WFIFOSET(sd->fd,len);
}
@@ -580,7 +600,7 @@ static int clif_set009e(struct flooritem_data *fitem,unsigned char *buf) {
*------------------------------------------
*/
int clif_dropflooritem(struct flooritem_data *fitem) {
- char buf[64];
+ unsigned char buf[64];
nullpo_retr(0, fitem);
@@ -685,7 +705,7 @@ static int clif_set0078(struct map_session_data *sd, unsigned char *buf) {
WBUFW(buf,0) = 0x78;
WBUFL(buf,2) = sd->bl.id;
- WBUFW(buf,6) = battle_get_speed(&sd->bl);
+ WBUFW(buf,6) = status_get_speed(&sd->bl);
WBUFW(buf,8) = sd->opt1;
WBUFW(buf,10) = sd->opt2;
WBUFW(buf,12) = sd->status.option;
@@ -697,7 +717,7 @@ static int clif_set0078(struct map_session_data *sd, unsigned char *buf) {
WBUFB(buf,49) = 5;
WBUFB(buf,50) = 5;
WBUFB(buf,51) = 0;
- WBUFW(buf,52) = ((level = battle_get_lv(&sd->bl)) > battle_config.max_lv) ? battle_config.max_lv : level;
+ WBUFW(buf,52) = ((level = status_get_lv(&sd->bl)) > battle_config.max_lv) ? battle_config.max_lv : level;
return packet_len_table[0x78];
}
@@ -775,7 +795,7 @@ static int clif_set0078(struct map_session_data *sd, unsigned char *buf) {
WBUFB(buf,49) = 5;
WBUFB(buf,50) = 5;
WBUFB(buf,51) = sd->state.dead_sit;
- WBUFW(buf,52) = ((level = battle_get_lv(&sd->bl)) > battle_config.max_lv) ? battle_config.max_lv : level;
+ WBUFW(buf,52) = ((level = status_get_lv(&sd->bl)) > battle_config.max_lv) ? battle_config.max_lv : level;
return packet_len_table[0x1d8];
#endif
@@ -794,7 +814,7 @@ static int clif_set007b(struct map_session_data *sd,unsigned char *buf) {
WBUFW(buf,0)=0x7b;
WBUFL(buf,2)=sd->bl.id;
- WBUFW(buf,6)=battle_get_speed(&sd->bl);
+ WBUFW(buf,6)=status_get_speed(&sd->bl);
WBUFW(buf,8)=sd->opt1;
WBUFW(buf,10)=sd->opt2;
WBUFW(buf,12)=sd->status.option;
@@ -806,7 +826,7 @@ static int clif_set007b(struct map_session_data *sd,unsigned char *buf) {
WBUFB(buf,55)=0;
WBUFB(buf,56)=5;
WBUFB(buf,57)=5;
- WBUFW(buf,58)=((level = battle_get_lv(&sd->bl))>battle_config.max_lv)? battle_config.max_lv:level;
+ WBUFW(buf,58)=((level = status_get_lv(&sd->bl))>battle_config.max_lv)? battle_config.max_lv:level;
return packet_len_table[0x7b];
}
@@ -896,17 +916,17 @@ static int clif_set007b(struct map_session_data *sd,unsigned char *buf) {
* ƒNƒ‰ƒXƒ`ƒFƒ“ƒW type‚ÍMob‚ÌꇂÍ1‚Å‘¼‚Í0H
*------------------------------------------
*/
-int clif_class_change(struct block_list *bl,int class,int type)
+int clif_class_change(struct block_list *bl,int class_,int type)
{
- char buf[16];
+ unsigned char buf[16];
nullpo_retr(0, bl);
- if(class >= MAX_PC_CLASS) {
+ if(class_ >= MAX_PC_CLASS) {
WBUFW(buf,0)=0x1b0;
WBUFL(buf,2)=bl->id;
WBUFB(buf,6)=type;
- WBUFL(buf,7)=class;
+ WBUFL(buf,7)=class_;
clif_send(buf,packet_len_table[0x1b0],bl,AREA);
}
@@ -916,9 +936,9 @@ int clif_class_change(struct block_list *bl,int class,int type)
*
*------------------------------------------
*/
-int clif_mob_class_change(struct mob_data *md, int class) {
- char buf[16];
- int view = mob_get_viewclass(class);
+int clif_mob_class_change(struct mob_data *md, int class_) {
+ unsigned char buf[16];
+ int view = mob_get_viewclass(class_);
nullpo_retr(0, md);
@@ -955,9 +975,9 @@ int clif_mob_equip(struct mob_data *md, int nameid) {
* MOB•\ަ1
*------------------------------------------
*/
-static int clif_mob0078(struct mob_data *md, unsigned char *buf)
+static int clif_mob0078(struct mob_data *md, unsigned char *buf)
{
- int level;
+ int level, i;
memset(buf,0,packet_len_table[0x78]);
@@ -965,25 +985,25 @@ static int clif_mob0078(struct mob_data *md, unsigned char *buf)
WBUFW(buf,0)=0x78;
WBUFL(buf,2)=md->bl.id;
- WBUFW(buf,6)=battle_get_speed(&md->bl);
+ WBUFW(buf,6)=status_get_speed(&md->bl);
WBUFW(buf,8)=md->opt1;
WBUFW(buf,10)=md->opt2;
WBUFW(buf,12)=md->option;
- WBUFW(buf,14)=mob_get_viewclass(md->class);
- if((mob_get_viewclass(md->class) <= 23) || (mob_get_viewclass(md->class) == 812) || (mob_get_viewclass(md->class) >= 4001)) {
- WBUFW(buf,12)|=mob_db[md->class].option;
- WBUFW(buf,16)=mob_get_hair(md->class);
- WBUFW(buf,18)=mob_get_weapon(md->class);
- WBUFW(buf,20)=mob_get_head_buttom(md->class);
- WBUFW(buf,22)=mob_get_shield(md->class);
- WBUFW(buf,24)=mob_get_head_top(md->class);
- WBUFW(buf,26)=mob_get_head_mid(md->class);
- WBUFW(buf,28)=mob_get_hair_color(md->class);
- WBUFW(buf,30)=mob_get_clothes_color(md->class); //Add for player monster dye - Valaris
- WBUFB(buf,45)=mob_get_sex(md->class);
- }
-
- if (md->class >= 1285 && md->class <= 1287 && md->guild_id) { // Added guardian emblems [Valaris]
+ WBUFW(buf,14)=mob_get_viewclass(md->class_);
+ if((i=mob_get_viewclass(md->class_)) <= 23 || i == 812 || i >= 4001) {
+ WBUFW(buf,12)|=mob_db[md->class_].option;
+ WBUFW(buf,16)=mob_get_hair(md->class_);
+ WBUFW(buf,18)=mob_get_weapon(md->class_);
+ WBUFW(buf,20)=mob_get_head_buttom(md->class_);
+ WBUFW(buf,22)=mob_get_shield(md->class_);
+ WBUFW(buf,24)=mob_get_head_top(md->class_);
+ WBUFW(buf,26)=mob_get_head_mid(md->class_);
+ WBUFW(buf,28)=mob_get_hair_color(md->class_);
+ WBUFW(buf,30)=mob_get_clothes_color(md->class_); //Add for player monster dye - Valaris
+ WBUFB(buf,45)=mob_get_sex(md->class_);
+ }
+
+ if (md->class_ >= 1285 && md->class_ <= 1287 && md->guild_id) { // Added guardian emblems [Valaris]
struct guild *g;
struct guild_castle *gc=guild_mapname2gc(map[md->bl.m].name);
if (gc && gc->guild_id > 0) {
@@ -999,7 +1019,7 @@ static int clif_mob0078(struct mob_data *md, unsigned char *buf)
WBUFB(buf,48)|=md->dir&0x0f;
WBUFB(buf,49)=5;
WBUFB(buf,50)=5;
- WBUFW(buf,52)=((level = battle_get_lv(&md->bl))>battle_config.max_lv)? battle_config.max_lv:level;
+ WBUFW(buf,52)=((level = status_get_lv(&md->bl))>battle_config.max_lv)? battle_config.max_lv:level;
return packet_len_table[0x78];
}
@@ -1017,27 +1037,27 @@ static int clif_mob007b(struct mob_data *md, unsigned char *buf) {
WBUFW(buf,0)=0x7b;
WBUFL(buf,2)=md->bl.id;
- WBUFW(buf,6)=battle_get_speed(&md->bl);
+ WBUFW(buf,6)=status_get_speed(&md->bl);
WBUFW(buf,8)=md->opt1;
WBUFW(buf,10)=md->opt2;
WBUFW(buf,12)=md->option;
- WBUFW(buf,14)=mob_get_viewclass(md->class);
- if ((mob_get_viewclass(md->class) < 24) || (mob_get_viewclass(md->class) > 4000)) {
- WBUFW(buf,12)|=mob_db[md->class].option;
- WBUFW(buf,16)=mob_get_hair(md->class);
- WBUFW(buf,18)=mob_get_weapon(md->class);
- WBUFW(buf,20)=mob_get_head_buttom(md->class);
+ WBUFW(buf,14)=mob_get_viewclass(md->class_);
+ if ((mob_get_viewclass(md->class_) < 24) || (mob_get_viewclass(md->class_) > 4000)) {
+ WBUFW(buf,12)|=mob_db[md->class_].option;
+ WBUFW(buf,16)=mob_get_hair(md->class_);
+ WBUFW(buf,18)=mob_get_weapon(md->class_);
+ WBUFW(buf,20)=mob_get_head_buttom(md->class_);
WBUFL(buf,22)=gettick();
- WBUFW(buf,26)=mob_get_shield(md->class);
- WBUFW(buf,28)=mob_get_head_top(md->class);
- WBUFW(buf,30)=mob_get_head_mid(md->class);
- WBUFW(buf,32)=mob_get_hair_color(md->class);
- WBUFW(buf,34)=mob_get_clothes_color(md->class); //Add for player monster dye - Valaris
- WBUFB(buf,49)=mob_get_sex(md->class);
+ WBUFW(buf,26)=mob_get_shield(md->class_);
+ WBUFW(buf,28)=mob_get_head_top(md->class_);
+ WBUFW(buf,30)=mob_get_head_mid(md->class_);
+ WBUFW(buf,32)=mob_get_hair_color(md->class_);
+ WBUFW(buf,34)=mob_get_clothes_color(md->class_); //Add for player monster dye - Valaris
+ WBUFB(buf,49)=mob_get_sex(md->class_);
} else
WBUFL(buf,22)=gettick();
- if(md->class >= 1285 && md->class <= 1287 && md->guild_id) { // Added guardian emblems [Valaris]
+ if(md->class_ >= 1285 && md->class_ <= 1287 && md->guild_id) { // Added guardian emblems [Valaris]
struct guild *g;
struct guild_castle *gc=guild_mapname2gc(map[md->bl.m].name);
if(gc && gc->guild_id > 0){
@@ -1052,7 +1072,7 @@ static int clif_mob007b(struct mob_data *md, unsigned char *buf) {
WBUFPOS2(buf,50,md->bl.x,md->bl.y,md->to_x,md->to_y);
WBUFB(buf,56)=5;
WBUFB(buf,57)=5;
- WBUFW(buf,58)=((level = battle_get_lv(&md->bl))>battle_config.max_lv)? battle_config.max_lv:level;
+ WBUFW(buf,58)=((level = status_get_lv(&md->bl))>battle_config.max_lv)? battle_config.max_lv:level;
return packet_len_table[0x7b];
}
@@ -1071,8 +1091,8 @@ static int clif_npc0078(struct npc_data *nd, unsigned char *buf) {
WBUFW(buf,0)=0x78;
WBUFL(buf,2)=nd->bl.id;
WBUFW(buf,6)=nd->speed;
- WBUFW(buf,14)=nd->class;
- if ((nd->class == 722) && (nd->u.scr.guild_id > 0) && ((g=guild_search(nd->u.scr.guild_id)) != NULL)) {
+ WBUFW(buf,14)=nd->class_;
+ if ((nd->class_ == 722) && (nd->u.scr.guild_id > 0) && ((g=guild_search(nd->u.scr.guild_id)) != NULL)) {
WBUFL(buf,22)=g->emblem_id;
WBUFL(buf,26)=g->guild_id;
}
@@ -1095,8 +1115,8 @@ static int clif_npc007b(struct npc_data *nd, unsigned char *buf) {
WBUFW(buf,0)=0x7b;
WBUFL(buf,2)=nd->bl.id;
WBUFW(buf,6)=nd->speed;
- WBUFW(buf,14)=nd->class;
- if ((nd->class == 722) && (nd->u.scr.guild_id > 0) && ((g=guild_search(nd->u.scr.guild_id)) != NULL)) {
+ WBUFW(buf,14)=nd->class_;
+ if ((nd->class_ == 722) && (nd->u.scr.guild_id > 0) && ((g=guild_search(nd->u.scr.guild_id)) != NULL)) {
WBUFL(buf,22)=g->emblem_id;
WBUFL(buf,26)=g->guild_id;
}
@@ -1123,18 +1143,18 @@ static int clif_pet0078(struct pet_data *pd, unsigned char *buf) {
WBUFW(buf,0)=0x78;
WBUFL(buf,2)=pd->bl.id;
WBUFW(buf,6)=pd->speed;
- WBUFW(buf,14)=mob_get_viewclass(pd->class);
- if((mob_get_viewclass(pd->class) < 24) || (mob_get_viewclass(pd->class) > 4000)) {
- WBUFW(buf,12)=mob_db[pd->class].option;
- WBUFW(buf,16)=mob_get_hair(pd->class);
- WBUFW(buf,18)=mob_get_weapon(pd->class);
- WBUFW(buf,20)=mob_get_head_buttom(pd->class);
- WBUFW(buf,22)=mob_get_shield(pd->class);
- WBUFW(buf,24)=mob_get_head_top(pd->class);
- WBUFW(buf,26)=mob_get_head_mid(pd->class);
- WBUFW(buf,28)=mob_get_hair_color(pd->class);
- WBUFW(buf,30)=mob_get_clothes_color(pd->class); //Add for player pet dye - Valaris
- WBUFB(buf,45)=mob_get_sex(pd->class);
+ WBUFW(buf,14)=mob_get_viewclass(pd->class_);
+ if((mob_get_viewclass(pd->class_) < 24) || (mob_get_viewclass(pd->class_) > 4000)) {
+ WBUFW(buf,12)=mob_db[pd->class_].option;
+ WBUFW(buf,16)=mob_get_hair(pd->class_);
+ WBUFW(buf,18)=mob_get_weapon(pd->class_);
+ WBUFW(buf,20)=mob_get_head_buttom(pd->class_);
+ WBUFW(buf,22)=mob_get_shield(pd->class_);
+ WBUFW(buf,24)=mob_get_head_top(pd->class_);
+ WBUFW(buf,26)=mob_get_head_mid(pd->class_);
+ WBUFW(buf,28)=mob_get_hair_color(pd->class_);
+ WBUFW(buf,30)=mob_get_clothes_color(pd->class_); //Add for player pet dye - Valaris
+ WBUFB(buf,45)=mob_get_sex(pd->class_);
} else {
WBUFW(buf,16)=0x14;
if((view = itemdb_viewid(pd->equip)) > 0)
@@ -1146,7 +1166,7 @@ static int clif_pet0078(struct pet_data *pd, unsigned char *buf) {
WBUFB(buf,48)|=pd->dir&0x0f;
WBUFB(buf,49)=0;
WBUFB(buf,50)=0;
- WBUFW(buf,52)=((level = battle_get_lv(&pd->bl))>battle_config.max_lv)? battle_config.max_lv:level;
+ WBUFW(buf,52)=((level = status_get_lv(&pd->bl))>battle_config.max_lv)? battle_config.max_lv:level;
return packet_len_table[0x78];
}
@@ -1165,19 +1185,19 @@ static int clif_pet007b(struct pet_data *pd, unsigned char *buf) {
WBUFW(buf,0)=0x7b;
WBUFL(buf,2)=pd->bl.id;
WBUFW(buf,6)=pd->speed;
- WBUFW(buf,14)=mob_get_viewclass(pd->class);
- if((mob_get_viewclass(pd->class) < 24) || (mob_get_viewclass(pd->class) > 4000)) {
- WBUFW(buf,12)=mob_db[pd->class].option;
- WBUFW(buf,16)=mob_get_hair(pd->class);
- WBUFW(buf,18)=mob_get_weapon(pd->class);
- WBUFW(buf,20)=mob_get_head_buttom(pd->class);
+ WBUFW(buf,14)=mob_get_viewclass(pd->class_);
+ if((mob_get_viewclass(pd->class_) < 24) || (mob_get_viewclass(pd->class_) > 4000)) {
+ WBUFW(buf,12)=mob_db[pd->class_].option;
+ WBUFW(buf,16)=mob_get_hair(pd->class_);
+ WBUFW(buf,18)=mob_get_weapon(pd->class_);
+ WBUFW(buf,20)=mob_get_head_buttom(pd->class_);
WBUFL(buf,22)=gettick();
- WBUFW(buf,26)=mob_get_shield(pd->class);
- WBUFW(buf,28)=mob_get_head_top(pd->class);
- WBUFW(buf,30)=mob_get_head_mid(pd->class);
- WBUFW(buf,32)=mob_get_hair_color(pd->class);
- WBUFW(buf,34)=mob_get_clothes_color(pd->class); //Add for player pet dye - Valaris
- WBUFB(buf,49)=mob_get_sex(pd->class);
+ WBUFW(buf,26)=mob_get_shield(pd->class_);
+ WBUFW(buf,28)=mob_get_head_top(pd->class_);
+ WBUFW(buf,30)=mob_get_head_mid(pd->class_);
+ WBUFW(buf,32)=mob_get_hair_color(pd->class_);
+ WBUFW(buf,34)=mob_get_clothes_color(pd->class_); //Add for player pet dye - Valaris
+ WBUFB(buf,49)=mob_get_sex(pd->class_);
} else {
WBUFW(buf,16)=0x14;
if ((view = itemdb_viewid(pd->equip)) > 0)
@@ -1189,7 +1209,7 @@ static int clif_pet007b(struct pet_data *pd, unsigned char *buf) {
WBUFPOS2(buf,50,pd->bl.x,pd->bl.y,pd->to_x,pd->to_y);
WBUFB(buf,56)=0;
WBUFB(buf,57)=0;
- WBUFW(buf,58)=((level = battle_get_lv(&pd->bl))>battle_config.max_lv)? battle_config.max_lv:level;
+ WBUFW(buf,58)=((level = status_get_lv(&pd->bl))>battle_config.max_lv)? battle_config.max_lv:level;
return packet_len_table[0x7b];
}
@@ -1281,11 +1301,11 @@ int clif_spawnpc(struct map_session_data *sd) {
clif_guild_emblem(sd,g);
} // end addition [Valaris]
- if (sd->status.class==13 || sd->status.class==21 || sd->status.class==4014 || sd->status.class==4022)
+ if (sd->status.class_==13 || sd->status.class_==21 || sd->status.class_==4014 || sd->status.class_==4022)
pc_setoption(sd,sd->status.option|0x0020); // [Valaris]
- if ((pc_isriding(sd) && pc_checkskill(sd,KN_RIDING)>0) && (sd->status.class==7 ||
- sd->status.class==14 || sd->status.class==4008 || sd->status.class==4015))
+ if ((pc_isriding(sd) && pc_checkskill(sd,KN_RIDING)>0) && (sd->status.class_==7 ||
+ sd->status.class_==14 || sd->status.class_==4008 || sd->status.class_==4015))
pc_setriding(sd); // update peco riders for people upgrading athena [Valaris]
@@ -1314,7 +1334,7 @@ int clif_spawnnpc(struct npc_data *nd)
nullpo_retr(0, nd);
- if(nd->class < 0 || nd->flag&1 || nd->class == INVISIBLE_CLASS)
+ if(nd->class_ < 0 || nd->flag&1 || nd->class_ == INVISIBLE_CLASS)
return 0;
memset(buf,0,packet_len_table[0x7c]);
@@ -1322,7 +1342,7 @@ int clif_spawnnpc(struct npc_data *nd)
WBUFW(buf,0)=0x7c;
WBUFL(buf,2)=nd->bl.id;
WBUFW(buf,6)=nd->speed;
- WBUFW(buf,20)=nd->class;
+ WBUFW(buf,20)=nd->class_;
WBUFPOS(buf,36,nd->bl.x,nd->bl.y);
clif_send(buf,packet_len_table[0x7c],&nd->bl,AREA);
@@ -1344,7 +1364,7 @@ int clif_spawnmob(struct mob_data *md)
nullpo_retr(0, md);
- if (mob_get_viewclass(md->class) > 23 ) {
+ if (mob_get_viewclass(md->class_) > 23) {
memset(buf,0,packet_len_table[0x7c]);
WBUFW(buf,0)=0x7c;
@@ -1353,7 +1373,7 @@ int clif_spawnmob(struct mob_data *md)
WBUFW(buf,8)=md->opt1;
WBUFW(buf,10)=md->opt2;
WBUFW(buf,12)=md->option;
- WBUFW(buf,20)=mob_get_viewclass(md->class);
+ WBUFW(buf,20)=mob_get_viewclass(md->class_);
WBUFPOS(buf,36,md->bl.x,md->bl.y);
clif_send(buf,packet_len_table[0x7c],&md->bl,AREA);
}
@@ -1361,8 +1381,8 @@ int clif_spawnmob(struct mob_data *md)
len = clif_mob0078(md,buf);
clif_send(buf,len,&md->bl,AREA);
- if (mob_get_equip(md->class) > 0) // mob equipment [Valaris]
- clif_mob_equip(md,mob_get_equip(md->class));
+ if (mob_get_equip(md->class_) > 0) // mob equipment [Valaris]
+ clif_mob_equip(md,mob_get_equip(md->class_));
if(md->size==2) // tiny/big mobs [Valaris]
clif_specialeffect(&md->bl,423,0);
@@ -1385,13 +1405,13 @@ int clif_spawnpet(struct pet_data *pd)
nullpo_retr(0, pd);
- if (mob_get_viewclass(pd->class) >= MAX_PC_CLASS) {
+ if (mob_get_viewclass(pd->class_) >= MAX_PC_CLASS) {
memset(buf,0,packet_len_table[0x7c]);
WBUFW(buf,0)=0x7c;
WBUFL(buf,2)=pd->bl.id;
WBUFW(buf,6)=pd->speed;
- WBUFW(buf,20)=mob_get_viewclass(pd->class);
+ WBUFW(buf,20)=mob_get_viewclass(pd->class_);
WBUFPOS(buf,36,pd->bl.x,pd->bl.y);
clif_send(buf,packet_len_table[0x7c],&pd->bl,AREA);
@@ -1517,6 +1537,7 @@ static int clif_waitclose(int tid, unsigned int tick, int id, int data) {
if (session[id])
session[id]->eof = 1;
+ close(id);
return 0;
}
@@ -1528,7 +1549,7 @@ void clif_setwaitclose(int fd) {
struct map_session_data *sd;
// if player is not already in the game (double connection probably)
- if ((sd = session[fd]->session_data) == NULL) {
+ if ((sd = (struct map_session_data*)session[fd]->session_data) == NULL) {
// limited timer, just to send information.
add_timer(gettick() + 1000, clif_waitclose, fd, 0);
} else
@@ -1584,7 +1605,7 @@ int clif_changemapserver(struct map_session_data *sd, char *mapname, int x, int
*------------------------------------------
*/
int clif_fixpos(struct block_list *bl) {
- char buf[16];
+ unsigned char buf[16];
nullpo_retr(0, bl);
@@ -1690,7 +1711,7 @@ int clif_scriptmes(struct map_session_data *sd, int npcid, char *mes) {
WFIFOW(fd,0)=0xb4;
WFIFOW(fd,2)=strlen(mes)+9;
WFIFOL(fd,4)=npcid;
- strcpy(WFIFOP(fd,8),mes);
+ strcpy((char*)WFIFOP(fd,8),mes);
WFIFOSET(fd,WFIFOW(fd,2));
return 0;
@@ -1743,7 +1764,7 @@ int clif_scriptmenu(struct map_session_data *sd, int npcid, char *mes) {
WFIFOW(fd,0)=0xb7;
WFIFOW(fd,2)=strlen(mes)+8;
WFIFOL(fd,4)=npcid;
- strcpy(WFIFOP(fd,8),mes);
+ strcpy((char*)WFIFOP(fd,8),mes);
WFIFOSET(fd,WFIFOW(fd,2));
return 0;
@@ -1816,7 +1837,7 @@ int clif_cutin(struct map_session_data *sd, char *image, int type) {
fd=sd->fd;
WFIFOW(fd,0)=0x1b3;
- memcpy(WFIFOP(fd,2),image,64);
+ strncpy((char*)WFIFOP(fd,2),image,64);
WFIFOB(fd,66)=type;
WFIFOSET(fd,packet_len_table[0x1b3]);
@@ -2067,9 +2088,9 @@ int clif_storageitemlist(struct map_session_data *sd,struct storage *stor)
#if PACKETVER < 5
WBUFW(buf,0)=0xa5;
for(i=0,n=0;i<MAX_STORAGE;i++){
- if(stor->storage[i].nameid<=0)
+ if(stor->storage_[i].nameid<=0)
continue;
- nullpo_retr(0, id = itemdb_search(stor->storage[i].nameid));
+ nullpo_retr(0, id = itemdb_search(stor->storage_[i].nameid));
if(itemdb_isequip2(id))
continue;
@@ -2077,10 +2098,10 @@ int clif_storageitemlist(struct map_session_data *sd,struct storage *stor)
if(id->view_id > 0)
WBUFW(buf,n*10+6)=id->view_id;
else
- WBUFW(buf,n*10+6)=stor->storage[i].nameid;
+ WBUFW(buf,n*10+6)=stor->storage_[i].nameid;
WBUFB(buf,n*10+8)=id->type;;
- WBUFB(buf,n*10+9)=stor->storage[i].identify;
- WBUFW(buf,n*10+10)=stor->storage[i].amount;
+ WBUFB(buf,n*10+9)=stor->storage_[i].identify;
+ WBUFW(buf,n*10+10)=stor->storage_[i].amount;
WBUFW(buf,n*10+12)=0;
n++;
}
@@ -2091,9 +2112,9 @@ int clif_storageitemlist(struct map_session_data *sd,struct storage *stor)
#else
WBUFW(buf,0)=0x1f0;
for(i=0,n=0;i<MAX_STORAGE;i++){
- if(stor->storage[i].nameid<=0)
+ if(stor->storage_[i].nameid<=0)
continue;
- nullpo_retr(0, id = itemdb_search(stor->storage[i].nameid));
+ nullpo_retr(0, id = itemdb_search(stor->storage_[i].nameid));
if(itemdb_isequip2(id))
continue;
@@ -2101,15 +2122,15 @@ int clif_storageitemlist(struct map_session_data *sd,struct storage *stor)
if(id->view_id > 0)
WBUFW(buf,n*18+6)=id->view_id;
else
- WBUFW(buf,n*18+6)=stor->storage[i].nameid;
+ WBUFW(buf,n*18+6)=stor->storage_[i].nameid;
WBUFB(buf,n*18+8)=id->type;;
- WBUFB(buf,n*18+9)=stor->storage[i].identify;
- WBUFW(buf,n*18+10)=stor->storage[i].amount;
+ WBUFB(buf,n*18+9)=stor->storage_[i].identify;
+ WBUFW(buf,n*18+10)=stor->storage_[i].amount;
WBUFW(buf,n*18+12)=0;
- WBUFW(buf,n*18+14)=stor->storage[i].card[0];
- WBUFW(buf,n*18+16)=stor->storage[i].card[1];
- WBUFW(buf,n*18+18)=stor->storage[i].card[2];
- WBUFW(buf,n*18+20)=stor->storage[i].card[3];
+ WBUFW(buf,n*18+14)=stor->storage_[i].card[0];
+ WBUFW(buf,n*18+16)=stor->storage_[i].card[1];
+ WBUFW(buf,n*18+18)=stor->storage_[i].card[2];
+ WBUFW(buf,n*18+20)=stor->storage_[i].card[3];
n++;
}
if(n){
@@ -2137,44 +2158,44 @@ int clif_storageequiplist(struct map_session_data *sd,struct storage *stor)
buf = WFIFOP(fd,0);
WBUFW(buf,0)=0xa6;
for(i=0,n=0;i<MAX_STORAGE;i++){
- if(stor->storage[i].nameid<=0)
+ if(stor->storage_[i].nameid<=0)
continue;
- nullpo_retr(0, id = itemdb_search(stor->storage[i].nameid));
+ nullpo_retr(0, id = itemdb_search(stor->storage_[i].nameid));
if(!itemdb_isequip2(id))
continue;
WBUFW(buf,n*20+4)=i+1;
if(id->view_id > 0)
WBUFW(buf,n*20+6)=id->view_id;
else
- WBUFW(buf,n*20+6)=stor->storage[i].nameid;
+ WBUFW(buf,n*20+6)=stor->storage_[i].nameid;
WBUFB(buf,n*20+8)=id->type;
- WBUFB(buf,n*20+9)=stor->storage[i].identify;
+ WBUFB(buf,n*20+9)=stor->storage_[i].identify;
WBUFW(buf,n*20+10)=id->equip;
- WBUFW(buf,n*20+12)=stor->storage[i].equip;
- WBUFB(buf,n*20+14)=stor->storage[i].attribute;
- WBUFB(buf,n*20+15)=stor->storage[i].refine;
- if(stor->storage[i].card[0]==0x00ff || stor->storage[i].card[0]==0x00fe || stor->storage[i].card[0]==(short)0xff00) {
- WBUFW(buf,n*20+16)=stor->storage[i].card[0];
- WBUFW(buf,n*20+18)=stor->storage[i].card[1];
- WBUFW(buf,n*20+20)=stor->storage[i].card[2];
- WBUFW(buf,n*20+22)=stor->storage[i].card[3];
+ WBUFW(buf,n*20+12)=stor->storage_[i].equip;
+ WBUFB(buf,n*20+14)=stor->storage_[i].attribute;
+ WBUFB(buf,n*20+15)=stor->storage_[i].refine;
+ if(stor->storage_[i].card[0]==0x00ff || stor->storage_[i].card[0]==0x00fe || stor->storage_[i].card[0]==(short)0xff00) {
+ WBUFW(buf,n*20+16)=stor->storage_[i].card[0];
+ WBUFW(buf,n*20+18)=stor->storage_[i].card[1];
+ WBUFW(buf,n*20+20)=stor->storage_[i].card[2];
+ WBUFW(buf,n*20+22)=stor->storage_[i].card[3];
} else {
- if(stor->storage[i].card[0] > 0 && (j=itemdb_viewid(stor->storage[i].card[0])) > 0)
+ if(stor->storage_[i].card[0] > 0 && (j=itemdb_viewid(stor->storage_[i].card[0])) > 0)
WBUFW(buf,n*20+16)=j;
else
- WBUFW(buf,n*20+16)=stor->storage[i].card[0];
- if(stor->storage[i].card[1] > 0 && (j=itemdb_viewid(stor->storage[i].card[1])) > 0)
+ WBUFW(buf,n*20+16)=stor->storage_[i].card[0];
+ if(stor->storage_[i].card[1] > 0 && (j=itemdb_viewid(stor->storage_[i].card[1])) > 0)
WBUFW(buf,n*20+18)=j;
else
- WBUFW(buf,n*20+18)=stor->storage[i].card[1];
- if(stor->storage[i].card[2] > 0 && (j=itemdb_viewid(stor->storage[i].card[2])) > 0)
+ WBUFW(buf,n*20+18)=stor->storage_[i].card[1];
+ if(stor->storage_[i].card[2] > 0 && (j=itemdb_viewid(stor->storage_[i].card[2])) > 0)
WBUFW(buf,n*20+20)=j;
else
- WBUFW(buf,n*20+20)=stor->storage[i].card[2];
- if(stor->storage[i].card[3] > 0 && (j=itemdb_viewid(stor->storage[i].card[3])) > 0)
+ WBUFW(buf,n*20+20)=stor->storage_[i].card[2];
+ if(stor->storage_[i].card[3] > 0 && (j=itemdb_viewid(stor->storage_[i].card[3])) > 0)
WBUFW(buf,n*20+22)=j;
else
- WBUFW(buf,n*20+22)=stor->storage[i].card[3];
+ WBUFW(buf,n*20+22)=stor->storage_[i].card[3];
}
n++;
}
@@ -2204,9 +2225,9 @@ int clif_guildstorageitemlist(struct map_session_data *sd,struct guild_storage *
#if PACKETVER < 5
WBUFW(buf,0)=0xa5;
for(i=0,n=0;i<MAX_GUILD_STORAGE;i++){
- if(stor->storage[i].nameid<=0)
+ if(stor->storage_[i].nameid<=0)
continue;
- nullpo_retr(0, id = itemdb_search(stor->storage[i].nameid));
+ nullpo_retr(0, id = itemdb_search(stor->storage_[i].nameid));
if(itemdb_isequip2(id))
continue;
@@ -2214,10 +2235,10 @@ int clif_guildstorageitemlist(struct map_session_data *sd,struct guild_storage *
if(id->view_id > 0)
WBUFW(buf,n*10+6)=id->view_id;
else
- WBUFW(buf,n*10+6)=stor->storage[i].nameid;
+ WBUFW(buf,n*10+6)=stor->storage_[i].nameid;
WBUFB(buf,n*10+8)=id->type;;
- WBUFB(buf,n*10+9)=stor->storage[i].identify;
- WBUFW(buf,n*10+10)=stor->storage[i].amount;
+ WBUFB(buf,n*10+9)=stor->storage_[i].identify;
+ WBUFW(buf,n*10+10)=stor->storage_[i].amount;
WBUFW(buf,n*10+12)=0;
n++;
}
@@ -2228,9 +2249,9 @@ int clif_guildstorageitemlist(struct map_session_data *sd,struct guild_storage *
#else
WBUFW(buf,0)=0x1f0;
for(i=0,n=0;i<MAX_GUILD_STORAGE;i++){
- if(stor->storage[i].nameid<=0)
+ if(stor->storage_[i].nameid<=0)
continue;
- nullpo_retr(0, id = itemdb_search(stor->storage[i].nameid));
+ nullpo_retr(0, id = itemdb_search(stor->storage_[i].nameid));
if(itemdb_isequip2(id))
continue;
@@ -2238,15 +2259,15 @@ int clif_guildstorageitemlist(struct map_session_data *sd,struct guild_storage *
if(id->view_id > 0)
WBUFW(buf,n*18+6)=id->view_id;
else
- WBUFW(buf,n*18+6)=stor->storage[i].nameid;
+ WBUFW(buf,n*18+6)=stor->storage_[i].nameid;
WBUFB(buf,n*18+8)=id->type;;
- WBUFB(buf,n*18+9)=stor->storage[i].identify;
- WBUFW(buf,n*18+10)=stor->storage[i].amount;
+ WBUFB(buf,n*18+9)=stor->storage_[i].identify;
+ WBUFW(buf,n*18+10)=stor->storage_[i].amount;
WBUFW(buf,n*18+12)=0;
- WBUFW(buf,n*18+14)=stor->storage[i].card[0];
- WBUFW(buf,n*18+16)=stor->storage[i].card[1];
- WBUFW(buf,n*18+18)=stor->storage[i].card[2];
- WBUFW(buf,n*18+20)=stor->storage[i].card[3];
+ WBUFW(buf,n*18+14)=stor->storage_[i].card[0];
+ WBUFW(buf,n*18+16)=stor->storage_[i].card[1];
+ WBUFW(buf,n*18+18)=stor->storage_[i].card[2];
+ WBUFW(buf,n*18+20)=stor->storage_[i].card[3];
n++;
}
if(n){
@@ -2274,44 +2295,44 @@ int clif_guildstorageequiplist(struct map_session_data *sd,struct guild_storage
WBUFW(buf,0)=0xa6;
for(i=0,n=0;i<MAX_GUILD_STORAGE;i++){
- if(stor->storage[i].nameid<=0)
+ if(stor->storage_[i].nameid<=0)
continue;
- nullpo_retr(0, id = itemdb_search(stor->storage[i].nameid));
+ nullpo_retr(0, id = itemdb_search(stor->storage_[i].nameid));
if(!itemdb_isequip2(id))
continue;
WBUFW(buf,n*20+4)=i+1;
if(id->view_id > 0)
WBUFW(buf,n*20+6)=id->view_id;
else
- WBUFW(buf,n*20+6)=stor->storage[i].nameid;
+ WBUFW(buf,n*20+6)=stor->storage_[i].nameid;
WBUFB(buf,n*20+8)=id->type;
- WBUFB(buf,n*20+9)=stor->storage[i].identify;
+ WBUFB(buf,n*20+9)=stor->storage_[i].identify;
WBUFW(buf,n*20+10)=id->equip;
- WBUFW(buf,n*20+12)=stor->storage[i].equip;
- WBUFB(buf,n*20+14)=stor->storage[i].attribute;
- WBUFB(buf,n*20+15)=stor->storage[i].refine;
- if(stor->storage[i].card[0]==0x00ff || stor->storage[i].card[0]==0x00fe || stor->storage[i].card[0]==(short)0xff00) {
- WBUFW(buf,n*20+16)=stor->storage[i].card[0];
- WBUFW(buf,n*20+18)=stor->storage[i].card[1];
- WBUFW(buf,n*20+20)=stor->storage[i].card[2];
- WBUFW(buf,n*20+22)=stor->storage[i].card[3];
+ WBUFW(buf,n*20+12)=stor->storage_[i].equip;
+ WBUFB(buf,n*20+14)=stor->storage_[i].attribute;
+ WBUFB(buf,n*20+15)=stor->storage_[i].refine;
+ if(stor->storage_[i].card[0]==0x00ff || stor->storage_[i].card[0]==0x00fe || stor->storage_[i].card[0]==(short)0xff00) {
+ WBUFW(buf,n*20+16)=stor->storage_[i].card[0];
+ WBUFW(buf,n*20+18)=stor->storage_[i].card[1];
+ WBUFW(buf,n*20+20)=stor->storage_[i].card[2];
+ WBUFW(buf,n*20+22)=stor->storage_[i].card[3];
} else {
- if(stor->storage[i].card[0] > 0 && (j=itemdb_viewid(stor->storage[i].card[0])) > 0)
+ if(stor->storage_[i].card[0] > 0 && (j=itemdb_viewid(stor->storage_[i].card[0])) > 0)
WBUFW(buf,n*20+16)=j;
else
- WBUFW(buf,n*20+16)=stor->storage[i].card[0];
- if(stor->storage[i].card[1] > 0 && (j=itemdb_viewid(stor->storage[i].card[1])) > 0)
+ WBUFW(buf,n*20+16)=stor->storage_[i].card[0];
+ if(stor->storage_[i].card[1] > 0 && (j=itemdb_viewid(stor->storage_[i].card[1])) > 0)
WBUFW(buf,n*20+18)=j;
else
- WBUFW(buf,n*20+18)=stor->storage[i].card[1];
- if(stor->storage[i].card[2] > 0 && (j=itemdb_viewid(stor->storage[i].card[2])) > 0)
+ WBUFW(buf,n*20+18)=stor->storage_[i].card[1];
+ if(stor->storage_[i].card[2] > 0 && (j=itemdb_viewid(stor->storage_[i].card[2])) > 0)
WBUFW(buf,n*20+20)=j;
else
- WBUFW(buf,n*20+20)=stor->storage[i].card[2];
- if(stor->storage[i].card[3] > 0 && (j=itemdb_viewid(stor->storage[i].card[3])) > 0)
+ WBUFW(buf,n*20+20)=stor->storage_[i].card[2];
+ if(stor->storage_[i].card[3] > 0 && (j=itemdb_viewid(stor->storage_[i].card[3])) > 0)
WBUFW(buf,n*20+22)=j;
else
- WBUFW(buf,n*20+22)=stor->storage[i].card[3];
+ WBUFW(buf,n*20+22)=stor->storage_[i].card[3];
}
n++;
}
@@ -2384,6 +2405,8 @@ int clif_updatestatus(struct map_session_data *sd,int type)
break;
case SP_HP:
WFIFOL(fd,4)=sd->status.hp;
+ if(battle_config.disp_hpmeter)
+ clif_hpmeter(sd);
break;
case SP_SP:
WFIFOL(fd,4)=sd->status.sp;
@@ -2828,7 +2851,7 @@ int clif_unequipitemack(struct map_session_data *sd,int n,int pos,int ok)
*/
int clif_misceffect(struct block_list* bl,int type)
{
- char buf[32];
+ unsigned char buf[32];
nullpo_retr(0, bl);
@@ -2862,7 +2885,7 @@ int clif_misceffect2(struct block_list *bl, int type) {
*/
int clif_changeoption(struct block_list* bl)
{
- char buf[32];
+ unsigned char buf[32];
short option;
struct status_change *sc_data;
static const int omask[]={ 0x10,0x20 };
@@ -2871,18 +2894,18 @@ int clif_changeoption(struct block_list* bl)
nullpo_retr(0, bl);
- option = *battle_get_option(bl);
- sc_data = battle_get_sc_data(bl);
+ option = *status_get_option(bl);
+ sc_data = status_get_sc_data(bl);
WBUFW(buf,0) = 0x119;
WBUFL(buf,2) = bl->id;
- WBUFW(buf,6) = *battle_get_opt1(bl);
- WBUFW(buf,8) = *battle_get_opt2(bl);
+ WBUFW(buf,6) = *status_get_opt1(bl);
+ WBUFW(buf,8) = *status_get_opt2(bl);
WBUFW(buf,10) = option;
WBUFB(buf,12) = 0; // ??
if(bl->type==BL_PC) { // disguises [Valaris]
- struct map_session_data *sd=((struct map_session_data *)bl);
+ struct map_session_data *sd=(struct map_session_data *)bl;
if(sd && sd->disguise > 23 && sd->disguise < 4001) {
clif_send(buf,packet_len_table[0x119],bl,AREA_WOS);
clif_spawnpc(sd);
@@ -2895,9 +2918,9 @@ int clif_changeoption(struct block_list* bl)
for(i=0;i<sizeof(omask)/sizeof(omask[0]);i++){
if( option&omask[i] ){
if( sc_data[scnum[i]].timer==-1)
- skill_status_change_start(bl,scnum[i],0,0,0,0,0,0);
+ status_change_start(bl,scnum[i],0,0,0,0,0,0);
} else {
- skill_status_change_end(bl,scnum[i],-1);
+ status_change_end(bl,scnum[i],-1);
}
}
@@ -2929,7 +2952,7 @@ int clif_useitemack(struct map_session_data *sd,int index,int amount,int ok)
WFIFOB(fd,6)=ok;
WFIFOSET(fd,packet_len_table[0xa8]);
#else
- char buf[32];
+ unsigned char buf[32];
WBUFW(buf,0)=0x1c8;
WBUFW(buf,2)=index+2;
@@ -2971,19 +2994,19 @@ int clif_createchat(struct map_session_data *sd,int fail)
*/
int clif_dispchat(struct chat_data *cd,int fd)
{
- char buf[128]; // Å‘åtitle(60ƒoƒCƒg)+17
+ unsigned char buf[128]; // Å‘åtitle(60ƒoƒCƒg)+17
if(cd==NULL || *cd->owner==NULL)
return 1;
WBUFW(buf,0)=0xd7;
- WBUFW(buf,2)=strlen(cd->title)+17;
+ WBUFW(buf,2)=strlen((const char*)cd->title)+17;
WBUFL(buf,4)=(*cd->owner)->id;
WBUFL(buf,8)=cd->bl.id;
WBUFW(buf,12)=cd->limit;
WBUFW(buf,14)=cd->users;
WBUFB(buf,16)=cd->pub;
- strcpy(WBUFP(buf,17),cd->title);
+ strcpy((char*)WBUFP(buf,17),(const char*)cd->title);
if(fd){
memcpy(WFIFOP(fd,0),buf,WBUFW(buf,2));
WFIFOSET(fd,WBUFW(buf,2));
@@ -3001,19 +3024,19 @@ int clif_dispchat(struct chat_data *cd,int fd)
*/
int clif_changechatstatus(struct chat_data *cd)
{
- char buf[128]; // Å‘åtitle(60ƒoƒCƒg)+17
+ unsigned char buf[128]; // Å‘åtitle(60ƒoƒCƒg)+17
if(cd==NULL || cd->usersd[0]==NULL)
return 1;
WBUFW(buf,0)=0xdf;
- WBUFW(buf,2)=strlen(cd->title)+17;
+ WBUFW(buf,2)=strlen((char*)cd->title)+17;
WBUFL(buf,4)=cd->usersd[0]->bl.id;
WBUFL(buf,8)=cd->bl.id;
WBUFW(buf,12)=cd->limit;
WBUFW(buf,14)=cd->users;
WBUFB(buf,16)=cd->pub;
- strcpy(WBUFP(buf,17),cd->title);
+ strcpy((char*)WBUFP(buf,17),(const char*)cd->title);
clif_send(buf,WBUFW(buf,2),&cd->usersd[0]->bl,CHAT);
return 0;
@@ -3025,7 +3048,7 @@ int clif_changechatstatus(struct chat_data *cd)
*/
int clif_clearchat(struct chat_data *cd,int fd)
{
- char buf[32];
+ unsigned char buf[32];
nullpo_retr(0, cd);
@@ -3091,7 +3114,7 @@ int clif_joinchatok(struct map_session_data *sd,struct chat_data* cd)
*/
int clif_addchat(struct chat_data* cd,struct map_session_data *sd)
{
- char buf[32];
+ unsigned char buf[32];
nullpo_retr(0, sd);
nullpo_retr(0, cd);
@@ -3110,7 +3133,7 @@ int clif_addchat(struct chat_data* cd,struct map_session_data *sd)
*/
int clif_changechatowner(struct chat_data* cd,struct map_session_data *sd)
{
- char buf[64];
+ unsigned char buf[64];
nullpo_retr(0, sd);
nullpo_retr(0, cd);
@@ -3133,7 +3156,7 @@ int clif_changechatowner(struct chat_data* cd,struct map_session_data *sd)
*/
int clif_leavechat(struct chat_data* cd,struct map_session_data *sd)
{
- char buf[32];
+ unsigned char buf[32];
nullpo_retr(0, sd);
nullpo_retr(0, cd);
@@ -3160,7 +3183,7 @@ int clif_traderequest(struct map_session_data *sd,char *name)
fd=sd->fd;
WFIFOW(fd,0)=0xe5;
- strcpy(WFIFOP(fd,2),name);
+ strcpy((char*)WFIFOP(fd,2),name);
WFIFOSET(fd,packet_len_table[0xe5]);
return 0;
@@ -3353,35 +3376,35 @@ int clif_storageitemadded(struct map_session_data *sd,struct storage *stor,int i
WFIFOW(fd,0) =0xf4; // Storage item added
WFIFOW(fd,2) =index+1; // index
WFIFOL(fd,4) =amount; // amount
- if((view = itemdb_viewid(stor->storage[index].nameid)) > 0)
+ if((view = itemdb_viewid(stor->storage_[index].nameid)) > 0)
WFIFOW(fd,8) =view;
else
- WFIFOW(fd,8) =stor->storage[index].nameid; // id
- WFIFOB(fd,10)=stor->storage[index].identify; //identify flag
- WFIFOB(fd,11)=stor->storage[index].attribute; // attribute
- WFIFOB(fd,12)=stor->storage[index].refine; //refine
- if(stor->storage[index].card[0]==0x00ff || stor->storage[index].card[0]==0x00fe || stor->storage[index].card[0]==(short)0xff00) {
- WFIFOW(fd,13)=stor->storage[index].card[0]; //card (4w)
- WFIFOW(fd,15)=stor->storage[index].card[1]; //card (4w)
- WFIFOW(fd,17)=stor->storage[index].card[2]; //card (4w)
- WFIFOW(fd,19)=stor->storage[index].card[3]; //card (4w)
+ WFIFOW(fd,8) =stor->storage_[index].nameid; // id
+ WFIFOB(fd,10)=stor->storage_[index].identify; //identify flag
+ WFIFOB(fd,11)=stor->storage_[index].attribute; // attribute
+ WFIFOB(fd,12)=stor->storage_[index].refine; //refine
+ if(stor->storage_[index].card[0]==0x00ff || stor->storage_[index].card[0]==0x00fe || stor->storage_[index].card[0]==(short)0xff00) {
+ WFIFOW(fd,13)=stor->storage_[index].card[0]; //card (4w)
+ WFIFOW(fd,15)=stor->storage_[index].card[1]; //card (4w)
+ WFIFOW(fd,17)=stor->storage_[index].card[2]; //card (4w)
+ WFIFOW(fd,19)=stor->storage_[index].card[3]; //card (4w)
} else {
- if(stor->storage[index].card[0] > 0 && (j=itemdb_viewid(stor->storage[index].card[0])) > 0)
+ if(stor->storage_[index].card[0] > 0 && (j=itemdb_viewid(stor->storage_[index].card[0])) > 0)
WFIFOW(fd,13)= j;
else
- WFIFOW(fd,13)= stor->storage[index].card[0];
- if(stor->storage[index].card[1] > 0 && (j=itemdb_viewid(stor->storage[index].card[1])) > 0)
+ WFIFOW(fd,13)= stor->storage_[index].card[0];
+ if(stor->storage_[index].card[1] > 0 && (j=itemdb_viewid(stor->storage_[index].card[1])) > 0)
WFIFOW(fd,15)= j;
else
- WFIFOW(fd,15)= stor->storage[index].card[1];
- if(stor->storage[index].card[2] > 0 && (j=itemdb_viewid(stor->storage[index].card[2])) > 0)
+ WFIFOW(fd,15)= stor->storage_[index].card[1];
+ if(stor->storage_[index].card[2] > 0 && (j=itemdb_viewid(stor->storage_[index].card[2])) > 0)
WFIFOW(fd,17)= j;
else
- WFIFOW(fd,17)= stor->storage[index].card[2];
- if(stor->storage[index].card[3] > 0 && (j=itemdb_viewid(stor->storage[index].card[3])) > 0)
+ WFIFOW(fd,17)= stor->storage_[index].card[2];
+ if(stor->storage_[index].card[3] > 0 && (j=itemdb_viewid(stor->storage_[index].card[3])) > 0)
WFIFOW(fd,19)= j;
else
- WFIFOW(fd,19)= stor->storage[index].card[3];
+ WFIFOW(fd,19)= stor->storage_[index].card[3];
}
WFIFOSET(fd,packet_len_table[0xf4]);
@@ -3423,35 +3446,35 @@ int clif_guildstorageitemadded(struct map_session_data *sd,struct guild_storage
WFIFOW(fd,0) =0xf4; // Storage item added
WFIFOW(fd,2) =index+1; // index
WFIFOL(fd,4) =amount; // amount
- if((view = itemdb_viewid(stor->storage[index].nameid)) > 0)
+ if((view = itemdb_viewid(stor->storage_[index].nameid)) > 0)
WFIFOW(fd,8) =view;
else
- WFIFOW(fd,8) =stor->storage[index].nameid; // id
- WFIFOB(fd,10)=stor->storage[index].identify; //identify flag
- WFIFOB(fd,11)=stor->storage[index].attribute; // attribute
- WFIFOB(fd,12)=stor->storage[index].refine; //refine
- if(stor->storage[index].card[0]==0x00ff || stor->storage[index].card[0]==0x00fe || stor->storage[index].card[0]==(short)0xff00) {
- WFIFOW(fd,13)=stor->storage[index].card[0]; //card (4w)
- WFIFOW(fd,15)=stor->storage[index].card[1]; //card (4w)
- WFIFOW(fd,17)=stor->storage[index].card[2]; //card (4w)
- WFIFOW(fd,19)=stor->storage[index].card[3]; //card (4w)
+ WFIFOW(fd,8) =stor->storage_[index].nameid; // id
+ WFIFOB(fd,10)=stor->storage_[index].identify; //identify flag
+ WFIFOB(fd,11)=stor->storage_[index].attribute; // attribute
+ WFIFOB(fd,12)=stor->storage_[index].refine; //refine
+ if(stor->storage_[index].card[0]==0x00ff || stor->storage_[index].card[0]==0x00fe || stor->storage_[index].card[0]==(short)0xff00) {
+ WFIFOW(fd,13)=stor->storage_[index].card[0]; //card (4w)
+ WFIFOW(fd,15)=stor->storage_[index].card[1]; //card (4w)
+ WFIFOW(fd,17)=stor->storage_[index].card[2]; //card (4w)
+ WFIFOW(fd,19)=stor->storage_[index].card[3]; //card (4w)
} else {
- if(stor->storage[index].card[0] > 0 && (j=itemdb_viewid(stor->storage[index].card[0])) > 0)
+ if(stor->storage_[index].card[0] > 0 && (j=itemdb_viewid(stor->storage_[index].card[0])) > 0)
WFIFOW(fd,13)= j;
else
- WFIFOW(fd,13)= stor->storage[index].card[0];
- if(stor->storage[index].card[1] > 0 && (j=itemdb_viewid(stor->storage[index].card[1])) > 0)
+ WFIFOW(fd,13)= stor->storage_[index].card[0];
+ if(stor->storage_[index].card[1] > 0 && (j=itemdb_viewid(stor->storage_[index].card[1])) > 0)
WFIFOW(fd,15)= j;
else
- WFIFOW(fd,15)= stor->storage[index].card[1];
- if(stor->storage[index].card[2] > 0 && (j=itemdb_viewid(stor->storage[index].card[2])) > 0)
+ WFIFOW(fd,15)= stor->storage_[index].card[1];
+ if(stor->storage_[index].card[2] > 0 && (j=itemdb_viewid(stor->storage_[index].card[2])) > 0)
WFIFOW(fd,17)= j;
else
- WFIFOW(fd,17)= stor->storage[index].card[2];
- if(stor->storage[index].card[3] > 0 && (j=itemdb_viewid(stor->storage[index].card[3])) > 0)
+ WFIFOW(fd,17)= stor->storage_[index].card[2];
+ if(stor->storage_[index].card[3] > 0 && (j=itemdb_viewid(stor->storage_[index].card[3])) > 0)
WFIFOW(fd,19)= j;
else
- WFIFOW(fd,19)= stor->storage[index].card[3];
+ WFIFOW(fd,19)= stor->storage_[index].card[3];
}
WFIFOSET(fd,packet_len_table[0xf4]);
@@ -3540,23 +3563,24 @@ void clif_getareachar_pc(struct map_session_data* sd,struct map_session_data* ds
* NPC•\ަ
*------------------------------------------
*/
+//fixed by Valaris
void clif_getareachar_npc(struct map_session_data* sd,struct npc_data* nd)
{
int len;
-
nullpo_retv(sd);
nullpo_retv(nd);
-
- if(nd->class < 0 || nd->flag&1 || nd->class == INVISIBLE_CLASS)
+ if(nd->class_ < 0 || nd->flag&1 || nd->class_ == INVISIBLE_CLASS)
return;
-
+ if(nd->state.state == MS_WALK){
+ len = clif_npc007b(nd,WFIFOP(sd->fd,0));
+ WFIFOSET(sd->fd,len);
+ } else {
len = clif_npc0078(nd,WFIFOP(sd->fd,0));
WFIFOSET(sd->fd,len);
-
+ }
if(nd->chat_id){
clif_dispchat((struct chat_data*)map_id2bl(nd->chat_id),sd->fd);
}
-
}
/*==========================================
@@ -3573,8 +3597,8 @@ int clif_movemob(struct mob_data *md)
len = clif_mob007b(md,buf);
clif_send(buf,len,&md->bl,AREA);
- if(mob_get_equip(md->class) > 0) // mob equipment [Valaris]
- clif_mob_equip(md,mob_get_equip(md->class));
+ if(mob_get_equip(md->class_) > 0) // mob equipment [Valaris]
+ clif_mob_equip(md,mob_get_equip(md->class_));
if(md->size==2) // tiny/big mobs [Valaris]
clif_specialeffect(&md->bl,423,0);
@@ -3681,12 +3705,13 @@ int clif_damage(struct block_list *src,struct block_list *dst,unsigned int tick,
nullpo_retr(0, src);
nullpo_retr(0, dst);
- sc_data = battle_get_sc_data(dst);
+ sc_data = status_get_sc_data(dst);
if(type != 4 && dst->type == BL_PC && ((struct map_session_data *)dst)->special_state.infinite_endure)
type = 9;
if(sc_data) {
- if(type != 4 && sc_data[SC_ENDURE].timer != -1)
+ if(type != 4 && sc_data[SC_ENDURE].timer != -1 &&
+ (dst->type == BL_PC && !map[dst->m].flag.gvg))
type = 9;
if(sc_data[SC_HALLUCINATION].timer != -1) {
if(damage > 0)
@@ -3721,6 +3746,9 @@ void clif_getareachar_mob(struct map_session_data* sd,struct mob_data* md)
nullpo_retv(sd);
nullpo_retv(md);
+ if (session[sd->fd] == NULL)
+ return;
+
if(md->state.state == MS_WALK){
len = clif_mob007b(md,WFIFOP(sd->fd,0));
WFIFOSET(sd->fd,len);
@@ -3729,14 +3757,14 @@ void clif_getareachar_mob(struct map_session_data* sd,struct mob_data* md)
WFIFOSET(sd->fd,len);
}
- if(mob_get_equip(md->class) > 0) // mob equipment [Valaris]
- clif_mob_equip(md,mob_get_equip(md->class));
+ if(mob_get_equip(md->class_) > 0) // mob equipment [Valaris]
+ clif_mob_equip(md,mob_get_equip(md->class_));
if(md->size==2) // tiny/big mobs [Valaris]
clif_specialeffect(&md->bl,423,0);
else if(md->size==1)
clif_specialeffect(&md->bl,421,0);
-
+
}
@@ -3868,7 +3896,7 @@ int clif_clearchar_skillunit(struct skill_unit *unit,int fd)
WFIFOW(fd, 0)=0x120;
WFIFOL(fd, 2)=unit->bl.id;
WFIFOSET(fd,packet_len_table[0x120]);
- if(unit->group->skill_id == WZ_ICEWALL)
+ if(unit->group && unit->group->skill_id == WZ_ICEWALL)
clif_set0192(fd,unit->bl.m,unit->bl.x,unit->bl.y,unit->val2);
return 0;
@@ -3880,7 +3908,7 @@ int clif_clearchar_skillunit(struct skill_unit *unit,int fd)
*/
int clif_01ac(struct block_list *bl)
{
- char buf[32];
+ unsigned char buf[32];
nullpo_retr(0, bl);
@@ -3904,6 +3932,9 @@ int clif_01ac(struct block_list *bl)
sd=va_arg(ap,struct map_session_data*);
+ if (sd == NULL || session[sd->fd] == NULL)
+ return 0;
+
switch(bl->type){
case BL_PC:
if(sd==(struct map_session_data*)bl)
@@ -3963,7 +3994,7 @@ int clif_pcoutsight(struct block_list *bl,va_list ap)
}
break;
case BL_NPC:
- if( ((struct npc_data *)bl)->class != INVISIBLE_CLASS )
+ if( ((struct npc_data *)bl)->class_ != INVISIBLE_CLASS )
clif_clearchar_id(bl->id,0,sd->fd);
break;
case BL_MOB:
@@ -4033,7 +4064,9 @@ int clif_moboutsight(struct block_list *bl,va_list ap)
nullpo_retr(0, ap);
nullpo_retr(0, md=va_arg(ap,struct mob_data*));
- if(bl->type==BL_PC && (sd = (struct map_session_data*) bl)){
+ if(bl->type==BL_PC
+ && ((sd = (struct map_session_data*) bl) != NULL)
+ && session[sd->fd] != NULL) {
clif_clearchar_id(md->bl.id,0,sd->fd);
}
@@ -4053,7 +4086,9 @@ int clif_mobinsight(struct block_list *bl,va_list ap)
nullpo_retr(0, ap);
md=va_arg(ap,struct mob_data*);
- if(bl->type==BL_PC && (sd = (struct map_session_data *)bl)){
+ if(bl->type==BL_PC
+ && ((sd = (struct map_session_data*) bl) != NULL)
+ && session[sd->fd] != NULL) {
clif_getareachar_mob(sd,md);
}
@@ -4073,7 +4108,9 @@ int clif_petoutsight(struct block_list *bl,va_list ap)
nullpo_retr(0, ap);
nullpo_retr(0, pd=va_arg(ap,struct pet_data*));
- if(bl->type==BL_PC && (sd = (struct map_session_data*) bl)){
+ if(bl->type==BL_PC
+ && ((sd = (struct map_session_data*) bl) != NULL)
+ && session[sd->fd] != NULL) {
clif_clearchar_id(pd->bl.id,0,sd->fd);
}
@@ -4090,7 +4127,9 @@ int clif_npcoutsight(struct block_list *bl,va_list ap)
nullpo_retr(0, ap);
nullpo_retr(0, nd=va_arg(ap,struct npc_data*));
- if(bl->type==BL_PC && (sd = (struct map_session_data*) bl)){
+ if(bl->type==BL_PC
+ && ((sd = (struct map_session_data*) bl) != NULL)
+ && session[sd->fd] != NULL) {
clif_clearchar_id(nd->bl.id,0,sd->fd);
}
@@ -4110,7 +4149,9 @@ int clif_petinsight(struct block_list *bl,va_list ap)
nullpo_retr(0, ap);
pd=va_arg(ap,struct pet_data*);
- if(bl->type==BL_PC && (sd = (struct map_session_data *)bl)){
+ if(bl->type==BL_PC
+ && ((sd = (struct map_session_data*) bl) != NULL)
+ && session[sd->fd] != NULL) {
clif_getareachar_pet(sd,pd);
}
@@ -4127,7 +4168,9 @@ int clif_npcinsight(struct block_list *bl,va_list ap)
nullpo_retr(0, ap);
nd=va_arg(ap,struct npc_data*);
- if(bl->type==BL_PC && (sd = (struct map_session_data *)bl)){
+ if(bl->type==BL_PC
+ && ((sd = (struct map_session_data*) bl) != NULL)
+ && session[sd->fd] != NULL) {
clif_getareachar_npc(sd,nd);
}
@@ -4159,14 +4202,14 @@ int clif_skillinfo(struct map_session_data *sd,int skillid,int type,int range)
if(range < 0) {
range = skill_get_range(id,sd->status.skill[skillid].lv);
if(range < 0)
- range = battle_get_range(&sd->bl) - (range + 1);
+ range = status_get_range(&sd->bl) - (range + 1);
WFIFOW(fd,12)= range;
} else
WFIFOW(fd,12)= range;
memset(WFIFOP(fd,14),0,24);
if(!(skill_get_inf2(id)&0x01) || battle_config.quest_skill_learn == 1 || (battle_config.gm_allskill > 0 && pc_isGM(sd) >= battle_config.gm_allskill) )
//WFIFOB(fd,38)= (sd->status.skill[skillid].lv < skill_get_max(id) && sd->status.skill[skillid].flag ==0 )? 1:0;
- WFIFOB(fd,38)= (sd->status.skill[skillid].lv < skill_tree_get_max(id, sd->status.class) && sd->status.skill[skillid].flag ==0 )? 1:0;
+ WFIFOB(fd,38)= (sd->status.skill[skillid].lv < skill_tree_get_max(id, sd->status.class_) && sd->status.skill[skillid].flag ==0 )? 1:0;
else
WFIFOB(fd,38) = 0;
WFIFOSET(fd,packet_len_table[0x147]);
@@ -4196,12 +4239,12 @@ int clif_skillinfoblock(struct map_session_data *sd)
WFIFOW(fd,len+8) = skill_get_sp(id,sd->status.skill[i].lv);
range = skill_get_range(id,sd->status.skill[i].lv);
if(range < 0)
- range = battle_get_range(&sd->bl) - (range + 1);
+ range = status_get_range(&sd->bl) - (range + 1);
WFIFOW(fd,len+10)= range;
memset(WFIFOP(fd,len+12),0,24);
if(!(skill_get_inf2(id)&0x01) || battle_config.quest_skill_learn == 1 || (battle_config.gm_allskill > 0 && pc_isGM(sd) >= battle_config.gm_allskill) )
//WFIFOB(fd,len+36)= (sd->status.skill[i].lv < skill_get_max(id) && sd->status.skill[i].flag ==0 )? 1:0;
- WFIFOB(fd,len+36)= (sd->status.skill[i].lv < skill_tree_get_max(id, sd->status.class) && sd->status.skill[i].flag ==0 )? 1:0;
+ WFIFOB(fd,len+36)= (sd->status.skill[i].lv < skill_tree_get_max(id, sd->status.class_) && sd->status.skill[i].flag ==0 )? 1:0;
else
WFIFOB(fd,len+36) = 0;
len+=37;
@@ -4231,10 +4274,10 @@ int clif_skillup(struct map_session_data *sd,int skill_num)
WFIFOW(fd,6) = skill_get_sp(skill_num,sd->status.skill[skill_num].lv);
range = skill_get_range(skill_num,sd->status.skill[skill_num].lv);
if(range < 0)
- range = battle_get_range(&sd->bl) - (range + 1);
+ range = status_get_range(&sd->bl) - (range + 1);
WFIFOW(fd,8) = range;
//WFIFOB(fd,10) = (sd->status.skill[skill_num].lv < skill_get_max(sd->status.skill[skill_num].id)) ? 1 : 0;
- WFIFOB(fd,10) = (sd->status.skill[skill_num].lv < skill_tree_get_max(sd->status.skill[skill_num].id, sd->status.class)) ? 1 : 0;
+ WFIFOB(fd,10) = (sd->status.skill[skill_num].lv < skill_tree_get_max(sd->status.skill[skill_num].id, sd->status.class_)) ? 1 : 0;
WFIFOSET(fd,packet_len_table[0x10e]);
return 0;
@@ -4290,7 +4333,12 @@ int clif_skill_fail(struct map_session_data *sd,int skill_id,int type,int btype)
fd=sd->fd;
- if(type==0x4 && battle_config.display_delay_skill_fail==0){
+ // reset all variables [celest]
+ sd->skillx = sd->skilly = -1;
+ sd->skillid = sd->skilllv = -1;
+ sd->skillitem = sd->skillitemlv = -1;
+
+ if(type==0x4 && (battle_config.display_delay_skill_fail==0 || sd->nodelay)){
return 0;
}
@@ -4318,7 +4366,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,
nullpo_retr(0, src);
nullpo_retr(0, dst);
- sc_data = battle_get_sc_data(dst);
+ sc_data = status_get_sc_data(dst);
if(type != 5 && dst->type == BL_PC && ((struct map_session_data *)dst)->special_state.infinite_endure)
type = 9;
@@ -4373,7 +4421,7 @@ int clif_skill_damage2(struct block_list *src,struct block_list *dst,
nullpo_retr(0, src);
nullpo_retr(0, dst);
- sc_data = battle_get_sc_data(dst);
+ sc_data = status_get_sc_data(dst);
if(type != 5 && dst->type == BL_PC && ((struct map_session_data *)dst)->special_state.infinite_endure)
type = 9;
@@ -4542,10 +4590,10 @@ int clif_skill_warppoint(struct map_session_data *sd,int skill_num,
fd=sd->fd;
WFIFOW(fd,0)=0x11c;
WFIFOW(fd,2)=skill_num;
- memcpy(WFIFOP(fd, 4),map1,16);
- memcpy(WFIFOP(fd,20),map2,16);
- memcpy(WFIFOP(fd,36),map3,16);
- memcpy(WFIFOP(fd,52),map4,16);
+ strncpy((char*)WFIFOP(fd, 4),map1,16);
+ strncpy((char*)WFIFOP(fd,20),map2,16);
+ strncpy((char*)WFIFOP(fd,36),map3,16);
+ strncpy((char*)WFIFOP(fd,52),map4,16);
WFIFOSET(fd,packet_len_table[0x11c]);
return 0;
}
@@ -4598,14 +4646,14 @@ int clif_skill_estimation(struct map_session_data *sd,struct block_list *dst)
return 0;
WBUFW(buf, 0)=0x18c;
- WBUFW(buf, 2)=mob_get_viewclass(md->class);
+ WBUFW(buf, 2)=mob_get_viewclass(md->class_);
WBUFW(buf, 4)=md->level;
- WBUFW(buf, 6)=mob_db[md->class].size;
+ WBUFW(buf, 6)=mob_db[md->class_].size;
WBUFL(buf, 8)=md->hp;
- WBUFW(buf,12)=battle_get_def2(&md->bl);
- WBUFW(buf,14)=mob_db[md->class].race;
- WBUFW(buf,16)=battle_get_mdef2(&md->bl) - (mob_db[md->class].vit>>1);
- WBUFW(buf,18)=battle_get_elem_type(&md->bl);
+ WBUFW(buf,12)=status_get_def2(&md->bl);
+ WBUFW(buf,14)=mob_db[md->class_].race;
+ WBUFW(buf,16)=status_get_mdef2(&md->bl) - (mob_db[md->class_].vit>>1);
+ WBUFW(buf,18)=status_get_elem_type(&md->bl);
for(i=0;i<9;i++)
WBUFB(buf,20+i)= battle_attr_fix(100,i+1,md->def_ele);
@@ -4668,8 +4716,11 @@ int clif_status_change(struct block_list *bl,int type,int flag)
* Send message (modified by [Yor])
*------------------------------------------
*/
-int clif_displaymessage(const int fd, char* mes)
+int clif_displaymessage(const int fd, char* mes)
{
+ // invalid pointer?
+ nullpo_retr(-1, mes);
+
//Console [Wizputer]
if (fd == 0)
printf("\033[0;36mConsole: \033[0m\033[1m%s\033[0m\n", mes);
@@ -4691,13 +4742,13 @@ int clif_displaymessage(const int fd, char* mes)
* “V‚̺‚ð‘—M‚·‚é
*------------------------------------------
*/
-int clif_GMmessage(struct block_list *bl, char* mes, int len, int flag)
+int clif_GMmessage(struct block_list *bl, char* mes, int len, int flag)
{
unsigned char *buf;
int lp;
lp = (flag & 0x10) ? 8 : 4;
- buf = (unsigned char*)aCalloc(len + lp, sizeof(unsigned char));
+ buf = (unsigned char*)aCallocA(len + lp, sizeof(unsigned char));
WBUFW(buf,0) = 0x9a;
WBUFW(buf,2) = len + lp;
@@ -4710,12 +4761,33 @@ int clif_GMmessage(struct block_list *bl, char* mes, int len, int flag)
(flag == 3) ? SELF :
ALL_CLIENT);
- if(buf) free(buf);
+ if(buf) aFree(buf);
return 0;
}
/*==========================================
+ * ƒOƒ[ƒoƒ‹ƒƒbƒZ[ƒW
+ *------------------------------------------
+ */
+void clif_GlobalMessage(struct block_list *bl,char *message)
+{
+ char buf[100];
+ int len,cmd=0x8d;
+
+ if(!bl || !message)
+ return;
+
+ len=strlen(message)+1;
+
+ WBUFW(buf,0)=cmd;
+ WBUFW(buf,2)=len+8;
+ WBUFL(buf,4)=bl->id;
+ strncpy((char *) WBUFP(buf,8),message,len);
+ clif_send((unsigned char *) buf,WBUFW(buf,2),bl,AREA_CHAT_WOC);
+}
+
+/*==========================================
* HPSP‰ñ•œƒGƒtƒFƒNƒg‚ð‘—M‚·‚é
*------------------------------------------
*/
@@ -4787,12 +4859,13 @@ int clif_pvpset(struct map_session_data *sd,int pvprank,int pvpnum,int type)
WFIFOL(sd->fd,10) = pvpnum;
WFIFOSET(sd->fd,packet_len_table[0x19a]);
} else {
- char buf[32];
+ unsigned char buf[32];
WBUFW(buf,0) = 0x19a;
WBUFL(buf,2) = sd->bl.id;
if(sd->status.option&0x46)
- WBUFL(buf,6) = -1;
+ // WTF? a -1 to an unsigned value...
+ WBUFL(buf,6) = 0xFFFFFFFF;
else
if(pvprank<=0)
pc_calc_pvprank(sd);
@@ -4814,7 +4887,7 @@ int clif_pvpset(struct map_session_data *sd,int pvprank,int pvpnum,int type)
int clif_send0199(int map,int type)
{
struct block_list bl;
- char buf[16];
+ unsigned char buf[16];
bl.m = map;
WBUFW(buf,0)=0x199;
@@ -4845,6 +4918,8 @@ int clif_refine(int fd,struct map_session_data *sd,int fail,int index,int val)
*/
int clif_wis_message(int fd, char *nick, char *mes, int mes_len) // R 0097 <len>.w <nick>.24B <message>.?B
{
+// printf("clif_wis_message(%d, %s, %s)\n", fd, nick, mes);
+
WFIFOW(fd,0) = 0x97;
WFIFOW(fd,2) = mes_len + 24 + 4;
memcpy(WFIFOP(fd,4), nick, 24);
@@ -4858,7 +4933,7 @@ int clif_wis_message(int fd, char *nick, char *mes, int mes_len) // R 0097 <len>
*------------------------------------------
*/
int clif_wis_end(int fd, int flag) // R 0098 <type>.B: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
-{
+{
WFIFOW(fd,0) = 0x98;
WFIFOW(fd,2) = flag;
WFIFOSET(fd,packet_len_table[0x98]);
@@ -5076,9 +5151,9 @@ int clif_item_skill(struct map_session_data *sd,int skillid,int skilllv,const ch
WFIFOW(fd,10)=skill_get_sp(skillid,skilllv);
range = skill_get_range(skillid,skilllv);
if(range < 0)
- range = battle_get_range(&sd->bl) - (range + 1);
+ range = status_get_range(&sd->bl) - (range + 1);
WFIFOW(fd,12)=range;
- memcpy(WFIFOP(fd,14),name,24);
+ strncpy((char*)WFIFOP(fd,14),name,24);
WFIFOB(fd,38)=0;
WFIFOSET(fd,packet_len_table[0x147]);
return 0;
@@ -5321,7 +5396,7 @@ int clif_showvendingboard(struct block_list* bl,char *message,int fd)
WBUFW(buf,0)=0x131;
WBUFL(buf,2)=bl->id;
- strncpy(WBUFP(buf,6),message,80);
+ strncpy((char*)WBUFP(buf,6),message,80);
if(fd){
memcpy(WFIFOP(fd,0),buf,packet_len_table[0x131]);
WFIFOSET(fd,packet_len_table[0x131]);
@@ -5535,6 +5610,8 @@ int clif_party_created(struct map_session_data *sd,int flag)
{
int fd;
+ // printf("clif_party_message(%s, %d, %s)\n", p->name, account_id, mes);
+
nullpo_retr(0, sd);
fd=sd->fd;
@@ -5748,6 +5825,70 @@ int clif_party_hp(struct party *p,struct map_session_data *sd)
return 0;
}
/*==========================================
+ * GM‚ÖꊂÆHP’Ê’m
+ *------------------------------------------
+ */
+int clif_hpmeter(struct map_session_data *sd)
+{
+ struct map_session_data *md;
+ unsigned char buf[16];
+ unsigned char buf2[16];
+ int i;
+
+ nullpo_retr(0, sd);
+
+ WBUFW(buf,0)=0x107;
+ WBUFL(buf,2)=sd->bl.id;
+ WBUFW(buf,6)=sd->bl.x;
+ WBUFW(buf,8)=sd->bl.y;
+
+ for(i=0;i<fd_max;i++){
+ if(session[i] && (md = (struct map_session_data*)session[i]->session_data) && md->state.auth &&
+ md->bl.m == sd->bl.m && pc_isGM(md) && sd != md){
+ memcpy(WFIFOP(i,0),buf,packet_len_table[0x107]);
+ WFIFOSET(i,packet_len_table[0x107]);
+ }
+ }
+
+ WBUFW(buf2,0)=0x106;
+ WBUFL(buf2,2)=sd->status.account_id;
+ WBUFW(buf2,6)=(sd->status.hp > 0x7fff)? 0x7fff:sd->status.hp;
+ WBUFW(buf2,8)=(sd->status.max_hp > 0x7fff)? 0x7fff:sd->status.max_hp;
+ for(i=0;i<fd_max;i++){
+ if(session[i] && (md = (struct map_session_data*)session[i]->session_data) && md->state.auth &&
+ md->bl.m == sd->bl.m && pc_isGM(md) && sd != md){
+ memcpy(WFIFOP(i,0),buf2,packet_len_table[0x106]);
+ WFIFOSET(i,packet_len_table[0x106]);
+ }
+ }
+
+ return 0;
+}
+/*==================================================
+ * Update monster hp view if it has changed [Celest]
+ *--------------------------------------------------
+ */
+int clif_update_mobhp(struct mob_data *md)
+{
+ unsigned char buf[102];
+ char mobhp[50];
+
+ nullpo_retr(0, md);
+
+ WBUFW(buf,0) = 0x95;
+ WBUFL(buf,2) = md->bl.id;
+
+ memcpy(WBUFP(buf,6), md->name, 24);
+ sprintf(mobhp, "hp: %d/%d", md->hp, mob_db[md->class_].max_hp);
+ WBUFW(buf, 0) = 0x195;
+ memcpy(WBUFP(buf,30), mobhp, 24);
+ WBUFL(buf,54) = 0;
+ WBUFL(buf,78) = 0;
+ clif_send(buf,packet_len_table[0x195],&md->bl,AREA);
+
+ return 0;
+}
+/*==========================================
* ƒp[ƒeƒBꊈړ®i–¢Žg—pj
*------------------------------------------
*/
@@ -5930,7 +6071,7 @@ int clif_pet_emotion(struct pet_data *pd,int param)
if(sd->petDB->talk_convert_class < 0)
return 0;
else if(sd->petDB->talk_convert_class > 0) {
- param -= (pd->class - 100)*100;
+ param -= (pd->class_ - 100)*100;
param += (sd->petDB->talk_convert_class - 100)*100;
}
}
@@ -6105,7 +6246,7 @@ int clif_combo_delay(struct block_list *bl,int wait)
*------------------------------------------
*/
int clif_bladestop(struct block_list *src,struct block_list *dst,
- int bool)
+ int _bool)
{
unsigned char buf[32];
@@ -6115,7 +6256,7 @@ int clif_bladestop(struct block_list *src,struct block_list *dst,
WBUFW(buf,0)=0x1d1;
WBUFL(buf,2)=src->id;
WBUFL(buf,6)=dst->id;
- WBUFL(buf,10)=bool;
+ WBUFL(buf,10)=_bool;
clif_send(buf,packet_len_table[0x1d1],src,AREA);
@@ -6129,7 +6270,7 @@ int clif_bladestop(struct block_list *src,struct block_list *dst,
int clif_changemapcell(int m,int x,int y,int cell_type,int type)
{
struct block_list bl;
- char buf[32];
+ unsigned char buf[32];
bl.m = m;
bl.x = x;
@@ -6247,6 +6388,8 @@ int clif_guild_memberlogin_notice(struct guild *g,int idx,int flag)
nullpo_retr(0, g);
+ // printf("clif_guild_message(%s, %d, %s)\n", g->name, account_id, mes);
+
WBUFW(buf, 0)=0x16d;
WBUFL(buf, 2)=g->member[idx].account_id;
WBUFL(buf, 6)=g->member[idx].char_id;
@@ -6317,32 +6460,32 @@ int clif_guild_basicinfo(struct map_session_data *sd)
if(g->guild_id == gc->guild_id) t++;
}
- if (t==1) memcpy(WFIFOP(fd,94),"One Castle",20);
- else if (t==2) memcpy(WFIFOP(fd,94),"Two Castles",20);
- else if (t==3) memcpy(WFIFOP(fd,94),"Three Castles",20);
- else if (t==4) memcpy(WFIFOP(fd,94),"Four Castles",20);
- else if (t==5) memcpy(WFIFOP(fd,94),"Five Castles",20);
- else if (t==6) memcpy(WFIFOP(fd,94),"Six Castles",20);
- else if (t==7) memcpy(WFIFOP(fd,94),"Seven Castles",20);
- else if (t==8) memcpy(WFIFOP(fd,94),"Eight Castles",20);
- else if (t==9) memcpy(WFIFOP(fd,94),"Nine Castles",20);
- else if (t==10) memcpy(WFIFOP(fd,94),"Ten Castles",20);
- else if (t==11) memcpy(WFIFOP(fd,94),"Eleven Castles",20);
- else if (t==12) memcpy(WFIFOP(fd,94),"Twelve Castles",20);
- else if (t==13) memcpy(WFIFOP(fd,94),"Thirteen Castles",20);
- else if (t==14) memcpy(WFIFOP(fd,94),"Fourteen Castles",20);
- else if (t==15) memcpy(WFIFOP(fd,94),"Fifteen Castles",20);
- else if (t==16) memcpy(WFIFOP(fd,94),"Sixteen Castles",20);
- else if (t==17) memcpy(WFIFOP(fd,94),"Seventeen Castles",20);
- else if (t==18) memcpy(WFIFOP(fd,94),"Eighteen Castles",20);
- else if (t==19) memcpy(WFIFOP(fd,94),"Nineteen Castles",20);
- else if (t==20) memcpy(WFIFOP(fd,94),"Twenty Castles",20);
- else if (t==21) memcpy(WFIFOP(fd,94),"Twenty One Castles",20);
- else if (t==22) memcpy(WFIFOP(fd,94),"Twenty Two Castles",20);
- else if (t==23) memcpy(WFIFOP(fd,94),"Twenty Three Castles",20);
- else if (t==24) memcpy(WFIFOP(fd,94),"Twenty Four Castles",20);
- else if (t==MAX_GUILDCASTLE) memcpy(WFIFOP(fd,94),"Total Domination",20);
- else memcpy(WFIFOP(fd,94),"None Taken",20);
+ if (t==1) strncpy((char*)WFIFOP(fd,94),"One Castle",20);
+ else if (t==2) strncpy((char*)WFIFOP(fd,94),"Two Castles",20);
+ else if (t==3) strncpy((char*)WFIFOP(fd,94),"Three Castles",20);
+ else if (t==4) strncpy((char*)WFIFOP(fd,94),"Four Castles",20);
+ else if (t==5) strncpy((char*)WFIFOP(fd,94),"Five Castles",20);
+ else if (t==6) strncpy((char*)WFIFOP(fd,94),"Six Castles",20);
+ else if (t==7) strncpy((char*)WFIFOP(fd,94),"Seven Castles",20);
+ else if (t==8) strncpy((char*)WFIFOP(fd,94),"Eight Castles",20);
+ else if (t==9) strncpy((char*)WFIFOP(fd,94),"Nine Castles",20);
+ else if (t==10) strncpy((char*)WFIFOP(fd,94),"Ten Castles",20);
+ else if (t==11) strncpy((char*)WFIFOP(fd,94),"Eleven Castles",20);
+ else if (t==12) strncpy((char*)WFIFOP(fd,94),"Twelve Castles",20);
+ else if (t==13) strncpy((char*)WFIFOP(fd,94),"Thirteen Castles",20);
+ else if (t==14) strncpy((char*)WFIFOP(fd,94),"Fourteen Castles",20);
+ else if (t==15) strncpy((char*)WFIFOP(fd,94),"Fifteen Castles",20);
+ else if (t==16) strncpy((char*)WFIFOP(fd,94),"Sixteen Castles",20);
+ else if (t==17) strncpy((char*)WFIFOP(fd,94),"Seventeen Castles",20);
+ else if (t==18) strncpy((char*)WFIFOP(fd,94),"Eighteen Castles",20);
+ else if (t==19) strncpy((char*)WFIFOP(fd,94),"Nineteen Castles",20);
+ else if (t==20) strncpy((char*)WFIFOP(fd,94),"Twenty Castles",20);
+ else if (t==21) strncpy((char*)WFIFOP(fd,94),"Twenty One Castles",20);
+ else if (t==22) strncpy((char*)WFIFOP(fd,94),"Twenty Two Castles",20);
+ else if (t==23) strncpy((char*)WFIFOP(fd,94),"Twenty Three Castles",20);
+ else if (t==24) strncpy((char*)WFIFOP(fd,94),"Twenty Four Castles",20);
+ else if (t==MAX_GUILDCASTLE) strncpy((char*)WFIFOP(fd,94),"Total Domination",20);
+ else strncpy((char*)WFIFOP(fd,94),"None Taken",20);
WFIFOSET(fd,packet_len_table[WFIFOW(fd,0)]);
clif_guild_emblem(sd,g); // Guild emblem vanish fix [Valaris]
@@ -6406,7 +6549,7 @@ int clif_guild_memberlist(struct map_session_data *sd)
WFIFOW(fd,c*104+12)=m->hair;
WFIFOW(fd,c*104+14)=m->hair_color;
WFIFOW(fd,c*104+16)=m->gender;
- WFIFOW(fd,c*104+18)=m->class;
+ WFIFOW(fd,c*104+18)=m->class_;
WFIFOW(fd,c*104+20)=m->lv;
WFIFOL(fd,c*104+22)=m->exp;
WFIFOL(fd,c*104+26)=m->online;
@@ -6564,35 +6707,51 @@ int clif_guild_skillinfo(struct map_session_data *sd)
memset(WFIFOP(fd,c*37+18),0,24);
if(g->skill[i].lv < guild_skill_get_max(id)) {
//Kafra and Guardian changed to require Approval [Sara]
- if (g->skill[i].id == GD_KAFRACONTACT && guild_checkskill(g,GD_APPROVAL) <= 0)
- up = 0;
- else if (g->skill[i].id == GD_GUARDIANRESEARCH && guild_checkskill(g,GD_APPROVAL) <= 0)
- up = 0;
- //Glory skill requirements -- Pretty sure correct [Sara]
- else if (g->skill[i].id == GD_LEADERSHIP && guild_checkskill(g,GD_GLORYGUILD) <= 0)
- up = 0;
- else if (g->skill[i].id == GD_GLORYWOUNDS && guild_checkskill(g,GD_GLORYGUILD) <= 0)
- up = 0;
- else if (g->skill[i].id == GD_SOULCOLD && guild_checkskill(g,GD_GLORYWOUNDS) <= 0)
- up = 0;
- else if (g->skill[i].id == GD_HAWKEYES && guild_checkskill(g,GD_LEADERSHIP) <= 0)
- up = 0;
- //Activated skill requirements -- Just guesses [Sara]
- else if (g->skill[i].id == GD_BATTLEORDER && guild_checkskill(g,GD_APPROVAL) <= 0)
- up = 0;
- else if (g->skill[i].id == GD_REGENERATION && guild_checkskill(g,GD_APPROVAL) <= 0)
- up = 0;
- else if (g->skill[i].id == GD_RESTORE && guild_checkskill(g,GD_REGENERATION) <= 0)
- up = 0;
- else if (g->skill[i].id == GD_EMERGENCYCALL && guild_checkskill(g,GD_APPROVAL) <= 0)
- up = 0;
- if (g->skill[i].id == GD_GUARDUP && guild_checkskill(g,GD_GUARDIANRESEARCH) <= 0)
- up = 0;
- //Unadded yet? Has extension description in kRO tables
- else if (g->skill[i].id == GD_DEVELOPMENT)
- up = 0;
- else
- up = 1;
+ switch (g->skill[i].id)
+ {
+ case GD_KAFRACONTACT:
+ case GD_GUARDIANRESEARCH:
+ case GD_GUARDUP:
+ case GD_DEVELOPMENT:
+ up = guild_checkskill(g,GD_APPROVAL) > 0;
+ break;
+ case GD_LEADERSHIP:
+ //Glory skill requirements -- Pretty sure correct [Sara]
+ up = (battle_config.require_glory_guild) ?
+ guild_checkskill(g,GD_GLORYGUILD) > 0 : 1;
+ // what skill does it need now that glory guild was removed? [celest]
+ break;
+ case GD_GLORYWOUNDS:
+ up = (battle_config.require_glory_guild) ?
+ guild_checkskill(g,GD_GLORYGUILD) > 0 : 1;
+ break;
+ case GD_SOULCOLD:
+ up = guild_checkskill(g,GD_GLORYWOUNDS) > 0;
+ break;
+ case GD_HAWKEYES:
+ up = guild_checkskill(g,GD_LEADERSHIP) > 0;
+ break;
+ case GD_BATTLEORDER:
+ up = guild_checkskill(g,GD_APPROVAL) > 0 &&
+ guild_checkskill(g,GD_EXTENSION) >= 2;
+ break;
+ case GD_REGENERATION:
+ up = guild_checkskill(g,GD_EXTENSION) >= 5 &&
+ guild_checkskill(g,GD_BATTLEORDER) > 0;
+ break;
+ case GD_RESTORE:
+ up = guild_checkskill(g,GD_REGENERATION) >= 2;
+ break;
+ case GD_EMERGENCYCALL:
+ up = guild_checkskill(g,GD_GUARDIANRESEARCH) > 0 &&
+ guild_checkskill(g,GD_REGENERATION) > 0;
+ break;
+ case GD_GLORYGUILD:
+ up = (battle_config.require_glory_guild) ? 1 : 0;
+ break;
+ default:
+ up = 1;
+ }
}
else {
up = 0;
@@ -6734,7 +6893,7 @@ int clif_guild_message(struct guild *g,int account_id,const char *mes,int len)
struct map_session_data *sd;
unsigned char *buf;
- buf = (unsigned char*)aCalloc(len + 4, sizeof(unsigned char));
+ buf = (unsigned char*)aCallocA(len + 4, sizeof(unsigned char));
WBUFW(buf, 0) = 0x17f;
WBUFW(buf, 2) = len + 4;
@@ -6743,7 +6902,7 @@ int clif_guild_message(struct guild *g,int account_id,const char *mes,int len)
if ((sd = guild_getavailablesd(g)) != NULL)
clif_send(buf, WBUFW(buf,2), &sd->bl, GUILD);
- if(buf) free(buf);
+ if(buf) aFree(buf);
return 0;
}
@@ -6937,10 +7096,34 @@ void clif_callpartner(struct map_session_data *sd)
}
*/
/*==========================================
+ * Adopt baby [Celest]
+ *------------------------------------------
+ */
+void clif_adopt_process(struct map_session_data *sd)
+{
+ int fd;
+ nullpo_retv(sd);
+
+ fd=sd->fd;
+ WFIFOW(fd,0)=0x1f8;
+ WFIFOSET(fd,packet_len_table[0x1f8]);
+}
+
+/*==========================================
+ *
+ *------------------------------------------
+ */
+void clif_parse_ReqAdopt(int fd, struct map_session_data *sd) {
+ nullpo_retv(sd);
+
+ printf ("%d\n", RFIFOL(fd,2));
+}
+
+/*==========================================
* À‚é
*------------------------------------------
*/
-void clif_sitting(struct map_session_data *sd)
+void clif_sitting(struct map_session_data *sd)
{
unsigned char buf[64];
@@ -6956,13 +7139,13 @@ void clif_sitting(struct map_session_data *sd)
*
*------------------------------------------
*/
-int clif_disp_onlyself(struct map_session_data *sd, char *mes, int len)
+int clif_disp_onlyself(struct map_session_data *sd, char *mes, int len)
{
unsigned char *buf;
nullpo_retr(0, sd);
- buf = (unsigned char*)aCalloc(len + 8, sizeof(unsigned char));
+ buf = (unsigned char*)aCallocA(len + 8, sizeof(unsigned char));
WBUFW(buf, 0) = 0x17f;
WBUFW(buf, 2) = len + 8;
@@ -6970,7 +7153,7 @@ int clif_disp_onlyself(struct map_session_data *sd, char *mes, int len)
clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);
- if(buf) free(buf);
+ if(buf) aFree(buf);
return 0;
}
@@ -6980,7 +7163,7 @@ int clif_disp_onlyself(struct map_session_data *sd, char *mes, int len)
*------------------------------------------
*/
-int clif_GM_kickack(struct map_session_data *sd, int id)
+int clif_GM_kickack(struct map_session_data *sd, int id)
{
int fd;
@@ -7009,6 +7192,25 @@ int clif_GM_kick(struct map_session_data *sd,struct map_session_data *tsd,int ty
return 0;
}
+
+/*==========================================
+ *
+ *------------------------------------------
+ */
+
+int clif_timedout(struct map_session_data *sd)
+{
+ nullpo_retr(0, sd);
+
+ sprintf(tmp_output,"%sCharacter with Account ID '"CL_WHITE"%d"CL_RESET"' timed out.\n", (pc_isGM(sd))?"GM ":"", sd->bl.id);
+ ShowInfo(tmp_output);
+ map_quit(sd);
+ clif_authfail_fd(sd->fd,3); // Even if player is not on we still send anyway
+ clif_setwaitclose(sd->fd); // Set session to EOF
+
+ return 0;
+}
+
/*==========================================
* Wis‹‘”Û‹–‰Â‰ž“š
*------------------------------------------
@@ -7066,6 +7268,24 @@ void clif_soundeffect(struct map_session_data *sd,struct block_list *bl,char *na
return;
}
+
+int clif_soundeffectall(struct block_list *bl, char *name, int type)
+{
+ unsigned char buf[31];
+ memset(buf, 0, packet_len_table[0x1d3]);
+
+ nullpo_retr(0, bl);
+
+ WBUFW(buf,0)=0x1d3;
+ memcpy(WBUFP(buf,2), name, 24);
+ WBUFB(buf,26)=type;
+ WBUFL(buf,27)=0;
+ WBUFL(buf,31)=bl->id;
+ clif_send(buf, packet_len_table[0x1d3], bl, AREA);
+
+ return 0;
+}
+
// displaying special effects (npcs, weather, etc) [Valaris]
int clif_specialeffect(struct block_list *bl, int type, int flag) {
unsigned char buf[24];
@@ -7083,8 +7303,8 @@ int clif_specialeffect(struct block_list *bl, int type, int flag) {
struct map_session_data *pl_sd;
int i;
for(i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) != NULL &&
- pl_sd->state.auth &&
+ if (session[i] && (pl_sd = (struct map_session_data*)session[i]->session_data) != NULL &&
+ pl_sd->state.auth &&
(pc_isGM((struct map_session_data *)&bl) > pc_isGM((struct map_session_data *)&pl_sd->bl)))
clif_specialeffect(&pl_sd->bl, type, 1);
}
@@ -7093,7 +7313,7 @@ int clif_specialeffect(struct block_list *bl, int type, int flag) {
struct map_session_data *sd;
int i;
for(i = 0; i < fd_max; i++) {
- if (session[i] && (sd = session[i]->session_data) != NULL && sd->state.auth && sd->bl.m == bl->m)
+ if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL && sd->state.auth && sd->bl.m == bl->m)
clif_specialeffect(&sd->bl, type, 1);
}
}
@@ -7106,6 +7326,14 @@ int clif_specialeffect(struct block_list *bl, int type, int flag) {
return 0;
}
+
+// refresh the client's screen, getting rid of any effects
+int clif_refresh(struct map_session_data *sd) {
+ nullpo_retr(-1, sd);
+ clif_changemap(sd,sd->mapname,sd->bl.x,sd->bl.y);
+ return 0;
+}
+
// ------------
// clif_parse_*
// ------------
@@ -7114,10 +7342,10 @@ int clif_specialeffect(struct block_list *bl, int type, int flag) {
*
*------------------------------------------
*/
-void clif_parse_WantToConnection(int fd, struct map_session_data *sd)
+void clif_parse_WantToConnection(int fd, struct map_session_data *sd)
{
struct map_session_data *old_sd;
- int account_id; // account_id in the packet 0x72 or 0x7E
+ int cmd, account_id; // account_id in the packet 0x72 or 0x7E
if (sd) {
if (battle_config.error_log)
@@ -7125,8 +7353,14 @@ void clif_parse_WantToConnection(int fd, struct map_session_data *sd)
return;
}
+ cmd = RFIFOW(fd,0);
+
+ // packet DB
+ if (IS_PACKET_DB_VER(cmd)) {
+ //printf("Received bytes %d with packet 0x72.\n", RFIFOREST(fd));
+ account_id = RFIFOL(fd,packet_db[clif_config.packet_db_ver][clif_config.connect_cmd].pos[0]);
// 0x72
- if (RFIFOW(fd,0) == 0x72) {
+ } else if (cmd == 0x72) {
//printf("Received bytes %d with packet 0x72.\n", RFIFOREST(fd));
if (RFIFOREST(fd) >= 39 && (RFIFOB(fd,38) == 0 || RFIFOB(fd,38) == 1)) // 00 = Female, 01 = Male
account_id = RFIFOL(fd,12);
@@ -7135,14 +7369,14 @@ void clif_parse_WantToConnection(int fd, struct map_session_data *sd)
else // old packet version
account_id = RFIFOL(fd,2);
// 0x7E
- } else if (RFIFOW(fd,0) == 0x7E) {
+ } else if (cmd == 0x7E) {
//printf("Received bytes %d with packet 0x7E.\n", RFIFOREST(fd));
if (RFIFOREST(fd) >= 37 && (RFIFOB(fd,36) == 0 || RFIFOB(fd,36) == 1)) // 00 = Female, 01 = Male
account_id = RFIFOL(fd,9);
else
account_id = RFIFOL(fd,12);
// 0xF5
- } else {
+ } else if (cmd == 0xF5) {
//printf("Received bytes %d with packet 0xF5.\n", RFIFOREST(fd));
if (RFIFOREST(fd) >= 34 && (RFIFOB(fd,33) == 0 || RFIFOB(fd,33) == 1)) // 00 = Female, 01 = Male
account_id = RFIFOL(fd,7);
@@ -7150,20 +7384,37 @@ void clif_parse_WantToConnection(int fd, struct map_session_data *sd)
account_id = RFIFOL(fd,12);
else if (RFIFOREST(fd) >= 32 && (RFIFOB(fd,31) == 0 || RFIFOB(fd,31) == 1)) // 00 = Female, 01 = Male
account_id = RFIFOL(fd,10);
- else // 29 28 28
- account_id = RFIFOL(fd,5);
+ else { // 29 28 28 // search correct value
+ // if account id and char id of version 14
+ if (RFIFOL(fd,3) > 700000 && RFIFOL(fd,10) >= 150000 && RFIFOL(fd,10) < 5000000) // account id / char id (more than 5.000.000 characters?) [Yor]
+ account_id = RFIFOL(fd,3);
+ else
+ account_id = RFIFOL(fd,5);
+ }
+ // 0x9B
+ } else {
+ account_id = RFIFOL(fd,3);
}
// if same account already connected, we disconnect the 2 sessions
if ((old_sd = map_id2sd(account_id)) != NULL) {
- clif_authfail_fd(fd, 2); // same id
+ clif_authfail_fd(fd, 8); // still recognizes last connection
clif_authfail_fd(old_sd->fd, 2); // same id
+ if (sd != 0)
+ clif_setwaitclose(sd->fd); // Set session to EOF
} else {
- sd = session[fd]->session_data = (struct map_session_data*)aCalloc(1, sizeof(struct map_session_data));
+ sd = (struct map_session_data*)aCalloc(1, sizeof(struct map_session_data));
+ session[fd]->session_data = sd;
sd->fd = fd;
+ if (IS_PACKET_DB_VER(cmd)) {
+ sd->packet_ver = clif_config.packet_db_ver; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ pc_setnewpc(sd, account_id, RFIFOL(fd,packet_db[clif_config.packet_db_ver][clif_config.connect_cmd].pos[1]),
+ RFIFOL(fd,packet_db[clif_config.packet_db_ver][clif_config.connect_cmd].pos[2]),
+ RFIFOL(fd,packet_db[clif_config.packet_db_ver][clif_config.connect_cmd].pos[3]),
+ RFIFOL(fd,packet_db[clif_config.packet_db_ver][clif_config.connect_cmd].pos[4]), fd);
// 0x72
- if (RFIFOW(fd,0) == 0x72) {
+ } else if (cmd == 0x72) {
if (RFIFOREST(fd) >= 39 && (RFIFOB(fd,38) == 0 || RFIFOB(fd,38) == 1)) { // 00 = Female, 01 = Male
sd->packet_ver = 7; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
pc_setnewpc(sd, account_id, RFIFOL(fd,22), RFIFOL(fd,30), RFIFOL(fd,34), RFIFOB(fd,38), fd);
@@ -7175,7 +7426,7 @@ void clif_parse_WantToConnection(int fd, struct map_session_data *sd)
pc_setnewpc(sd, account_id, RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOB(fd,18), fd);
}
// 0x7E
- } else if (RFIFOW(fd,0) == 0x7E) {
+ } else if (cmd == 0x7E) {
if (RFIFOREST(fd) >= 37 && (RFIFOB(fd,36) == 0 || RFIFOB(fd,36) == 1)) { // 00 = Female, 01 = Male
sd->packet_ver = 9; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
pc_setnewpc(sd, account_id, RFIFOL(fd,21), RFIFOL(fd,28), RFIFOL(fd,32), RFIFOB(fd,36), fd);
@@ -7184,7 +7435,7 @@ void clif_parse_WantToConnection(int fd, struct map_session_data *sd)
pc_setnewpc(sd, account_id, RFIFOL(fd,18), RFIFOL(fd,24), RFIFOL(fd,28), RFIFOB(fd,32), fd);
}
// 0xF5
- } else {
+ } else if (cmd == 0xF5) {
if (RFIFOREST(fd) >= 34 && (RFIFOB(fd,33) == 0 || RFIFOB(fd,33) == 1)) { // 00 = Female, 01 = Male
sd->packet_ver = 10; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
pc_setnewpc(sd, account_id, RFIFOL(fd,15), RFIFOL(fd,25), RFIFOL(fd,29), RFIFOB(fd,33), fd);
@@ -7195,9 +7446,19 @@ void clif_parse_WantToConnection(int fd, struct map_session_data *sd)
sd->packet_ver = 11; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
pc_setnewpc(sd, account_id, RFIFOL(fd,17), RFIFOL(fd,23), RFIFOL(fd,27), RFIFOB(fd,31), fd);
} else { // 29
- sd->packet_ver = 13; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
- pc_setnewpc(sd, account_id, RFIFOL(fd,14), RFIFOL(fd,20), RFIFOL(fd,24), RFIFOB(fd,28), fd);
+ // if account id and char id of version 14
+ if (RFIFOL(fd,3) > 700000 && RFIFOL(fd,10) >= 150000 && RFIFOL(fd,10) < 5000000) { // account id / char id (more than 5.000.000 characters?)
+ sd->packet_ver = 15; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ pc_setnewpc(sd, account_id, RFIFOL(fd,10), RFIFOL(fd,20), RFIFOL(fd,24), RFIFOB(fd,28), fd);
+ } else {
+ sd->packet_ver = 13; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ pc_setnewpc(sd, account_id, RFIFOL(fd,14), RFIFOL(fd,20), RFIFOL(fd,24), RFIFOB(fd,28), fd);
+ }
}
+ // 0x9B
+ } else {
+ sd->packet_ver = 16; // 16: 10jan05
+ pc_setnewpc(sd, account_id, RFIFOL(fd,12), RFIFOL(fd,23), RFIFOL(fd,27), RFIFOB(fd,31), fd);
}
WFIFOL(fd,0) = sd->bl.id;
@@ -7299,10 +7560,10 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
if(sd->state.connect_new) {
sd->state.connect_new = 0;
- if(sd->status.class != sd->view_class)
+ if(sd->status.class_ != sd->view_class)
clif_changelook(&sd->bl,LOOK_BASE,sd->view_class);
if(sd->status.pet_id > 0 && sd->pd && sd->pet.intimate > 900)
- clif_pet_emotion(sd->pd,(sd->pd->class - 100)*100 + 50 + pet_hungry_val(sd));
+ clif_pet_emotion(sd->pd,(sd->pd->class_ - 100)*100 + 50 + pet_hungry_val(sd));
/* Stop players from spawning inside castles [Valaris] */
@@ -7326,16 +7587,17 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
if(battle_config.save_clothcolor==1 && sd->status.clothes_color > 0)
clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->status.clothes_color);
- if(sd->status.hp<sd->status.max_hp>>2 && pc_checkskill(sd,SM_AUTOBERSERK)>0 &&
+ //if(sd->status.hp<sd->status.max_hp>>2 && pc_checkskill(sd,SM_AUTOBERSERK)>0 &&
+ if(sd->status.hp<sd->status.max_hp>>2 && sd->sc_data[SC_AUTOBERSERK].timer != -1 &&
(sd->sc_data[SC_PROVOKE].timer==-1 || sd->sc_data[SC_PROVOKE].val2==0 ))
// ƒI[ƒgƒo[ƒT[ƒN”­“®
- skill_status_change_start(&sd->bl,SC_PROVOKE,10,1,0,0,0,0);
-
+ status_change_start(&sd->bl,SC_PROVOKE,10,1,0,0,0,0);
+
// if(time(&timer) < ((weddingtime=pc_readglobalreg(sd,"PC_WEDDING_TIME")) + 3600))
-// skill_status_change_start(&sd->bl,SC_WEDDING,0,weddingtime,0,0,36000,0);
+// status_change_start(&sd->bl,SC_WEDDING,0,weddingtime,0,0,36000,0);
if(battle_config.muting_players && sd->status.manner < 0)
- skill_status_change_start(&sd->bl,SC_NOCHAT,0,0,0,0,0,0);
+ status_change_start(&sd->bl,SC_NOCHAT,0,0,0,0,0,0);
if (night_flag) {
if (battle_config.night_darkness_level > 0 && !map[sd->bl.m].flag.indoors)
@@ -7354,16 +7616,16 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
// option
clif_changeoption(&sd->bl);
if(sd->sc_data[SC_TRICKDEAD].timer != -1)
- skill_status_change_end(&sd->bl,SC_TRICKDEAD,-1);
+ status_change_end(&sd->bl,SC_TRICKDEAD,-1);
if(sd->sc_data[SC_SIGNUMCRUCIS].timer != -1 && !battle_check_undead(7,sd->def_ele))
- skill_status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1);
+ status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1);
if(sd->special_state.infinite_endure && sd->sc_data[SC_ENDURE].timer == -1)
- skill_status_change_start(&sd->bl,SC_ENDURE,10,1,0,0,0,0);
+ status_change_start(&sd->bl,SC_ENDURE,10,1,0,0,0,0);
for(i=0;i<MAX_INVENTORY;i++){
if(sd->status.inventory[i].equip && sd->status.inventory[i].equip & 0x0002 && sd->status.inventory[i].attribute==1)
- skill_status_change_start(&sd->bl,SC_BROKNWEAPON,0,0,0,0,0,0);
+ status_change_start(&sd->bl,SC_BROKNWEAPON,0,0,0,0,0,0);
if(sd->status.inventory[i].equip && sd->status.inventory[i].equip & 0x0010 && sd->status.inventory[i].attribute==1)
- skill_status_change_start(&sd->bl,SC_BROKNARMOR,0,0,0,0,0,0);
+ status_change_start(&sd->bl,SC_BROKNARMOR,0,0,0,0,0,0);
}
map_foreachinarea(clif_getareachar,sd->bl.m,sd->bl.x-AREA_SIZE,sd->bl.y-AREA_SIZE,sd->bl.x+AREA_SIZE,sd->bl.y+AREA_SIZE,0,sd);
@@ -7376,29 +7638,42 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
void clif_parse_TickSend(int fd, struct map_session_data *sd) {
nullpo_retv(sd);
- switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
- case 8:
- sd->client_tick = RFIFOL(fd,6);
- break;
- case 9:
- sd->client_tick = RFIFOL(fd,9);
- break;
- case 10:
- sd->client_tick = RFIFOL(fd,7);
- break;
- case 11:
- sd->client_tick = RFIFOL(fd,10);
- break;
- case 12:
- sd->client_tick = RFIFOL(fd,6);
- break;
- case 13:
- sd->client_tick = RFIFOL(fd,5);
- break;
- default: // old version by default (and version 6 + 7)
- sd->client_tick = RFIFOL(fd,2);
- break;
+ if (USE_PACKET_DB(sd)) {
+ sd->client_tick=RFIFOL(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0]);
+ } else {
+ switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ case 8:
+ sd->client_tick = RFIFOL(fd,6);
+ break;
+ case 9:
+ sd->client_tick = RFIFOL(fd,9);
+ break;
+ case 10:
+ sd->client_tick = RFIFOL(fd,7);
+ break;
+ case 11:
+ sd->client_tick = RFIFOL(fd,10);
+ break;
+ case 12:
+ sd->client_tick = RFIFOL(fd,6);
+ break;
+ case 13:
+ case 14:
+ sd->client_tick = RFIFOL(fd,5);
+ break;
+ case 15:
+ sd->client_tick = RFIFOL(fd,3);
+ break;
+ case 16:
+ sd->client_tick = RFIFOL(fd,5);
+ break;
+
+ default: // old version by default (and version 6 + 7)
+ sd->client_tick = RFIFOL(fd,2);
+ break;
+ }
}
+
sd->server_tick = gettick();
clif_servertick(sd);
}
@@ -7436,7 +7711,9 @@ void clif_parse_WalkToXY(int fd, struct map_session_data *sd) {
sd->sc_data[SC_TRICKDEAD].timer !=-1 || //Ž€‚ñ‚¾‚Ó‚è
sd->sc_data[SC_BLADESTOP].timer !=-1 || //”’nŽæ‚è
sd->sc_data[SC_SPIDERWEB].timer !=-1 || //ƒXƒpƒCƒ_[ƒEƒFƒbƒu
- (sd->sc_data[SC_DANCING].timer !=-1 && sd->sc_data[SC_DANCING].val4)) //‡‘tƒXƒLƒ‹‰‰‘t’†‚Í“®‚¯‚È‚¢
+ (sd->sc_data[SC_DANCING].timer !=-1 && sd->sc_data[SC_DANCING].val4) || //‡‘tƒXƒLƒ‹‰‰‘t’†‚Í“®‚¯‚È‚¢
+ (sd->sc_data[SC_GOSPEL].timer !=-1 && sd->sc_data[SC_GOSPEL].val4 == BCT_SELF) || // cannot move while gospel is in effect
+ sd->sc_data[SC_CONFUSION].timer !=-1)
return;
if ((sd->status.option & 2) && pc_checkskill(sd, RG_TUNNELDRIVE) <= 0)
return;
@@ -7446,43 +7723,60 @@ void clif_parse_WalkToXY(int fd, struct map_session_data *sd) {
pc_stopattack(sd);
- switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
- case 6:
- x = RFIFOB(fd,5) * 4 + (RFIFOB(fd,6) >> 6);
- y = ((RFIFOB(fd,6) & 0x3f) << 4) + (RFIFOB(fd,7) >> 4);
- break;
- case 7:
- x = RFIFOB(fd,6) * 4 + (RFIFOB(fd,7) >> 6);
- y = ((RFIFOB(fd,7) & 0x3f) << 4) + (RFIFOB(fd,8) >> 4);
- break;
- case 8:
- x = RFIFOB(fd,3) * 4 + (RFIFOB(fd,4) >> 6);
- y = ((RFIFOB(fd,4) & 0x3f) << 4) + (RFIFOB(fd,5) >> 4);
- break;
- case 9:
- x = RFIFOB(fd,12) * 4 + (RFIFOB(fd,13) >> 6);
- y = ((RFIFOB(fd,13) & 0x3f) << 4) + (RFIFOB(fd,14) >> 4);
- break;
- case 10:
- x = RFIFOB(fd,6) * 4 + (RFIFOB(fd,7) >> 6);
- y = ((RFIFOB(fd,7) & 0x3f) << 4) + (RFIFOB(fd,8) >> 4);
- break;
- case 11:
- x = RFIFOB(fd,11) * 4 + (RFIFOB(fd,12) >> 6);
- y = ((RFIFOB(fd,12) & 0x3f) << 4) + (RFIFOB(fd,13) >> 4);
- break;
- case 12:
- x = RFIFOB(fd,3) * 4 + (RFIFOB(fd,4) >> 6);
- y = ((RFIFOB(fd,4) & 0x3f) << 4) + (RFIFOB(fd,5) >> 4);
- break;
- case 13:
- x = RFIFOB(fd,3) * 4 + (RFIFOB(fd,4) >> 6);
- y = ((RFIFOB(fd,4) & 0x3f) << 4) + (RFIFOB(fd,5) >> 4);
- break;
- default: // old version by default
- x = RFIFOB(fd,2) * 4 + (RFIFOB(fd,3) >> 6);
- y = ((RFIFOB(fd,3) & 0x3f) << 4) + (RFIFOB(fd,4) >> 4);
- break;
+ if (USE_PACKET_DB(sd)) {
+ int cmd = RFIFOW(fd,0);
+ x = RFIFOB(fd,packet_db[clif_config.packet_db_ver][cmd].pos[0]) * 4 +
+ (RFIFOB(fd,packet_db[clif_config.packet_db_ver][cmd].pos[0] + 1) >> 6);
+ y = ((RFIFOB(fd,packet_db[clif_config.packet_db_ver][cmd].pos[0]+1) & 0x3f) << 4) +
+ (RFIFOB(fd,packet_db[clif_config.packet_db_ver][cmd].pos[0] + 2) >> 4);
+ } else {
+ switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ case 6:
+ x = RFIFOB(fd,5) * 4 + (RFIFOB(fd,6) >> 6);
+ y = ((RFIFOB(fd,6) & 0x3f) << 4) + (RFIFOB(fd,7) >> 4);
+ break;
+ case 7:
+ x = RFIFOB(fd,6) * 4 + (RFIFOB(fd,7) >> 6);
+ y = ((RFIFOB(fd,7) & 0x3f) << 4) + (RFIFOB(fd,8) >> 4);
+ break;
+ case 8:
+ x = RFIFOB(fd,3) * 4 + (RFIFOB(fd,4) >> 6);
+ y = ((RFIFOB(fd,4) & 0x3f) << 4) + (RFIFOB(fd,5) >> 4);
+ break;
+ case 9:
+ x = RFIFOB(fd,12) * 4 + (RFIFOB(fd,13) >> 6);
+ y = ((RFIFOB(fd,13) & 0x3f) << 4) + (RFIFOB(fd,14) >> 4);
+ break;
+ case 10:
+ x = RFIFOB(fd,6) * 4 + (RFIFOB(fd,7) >> 6);
+ y = ((RFIFOB(fd,7) & 0x3f) << 4) + (RFIFOB(fd,8) >> 4);
+ break;
+ case 11:
+ x = RFIFOB(fd,11) * 4 + (RFIFOB(fd,12) >> 6);
+ y = ((RFIFOB(fd,12) & 0x3f) << 4) + (RFIFOB(fd,13) >> 4);
+ break;
+ case 12:
+ x = RFIFOB(fd,3) * 4 + (RFIFOB(fd,4) >> 6);
+ y = ((RFIFOB(fd,4) & 0x3f) << 4) + (RFIFOB(fd,5) >> 4);
+ break;
+ case 13:
+ case 14:
+ x = RFIFOB(fd,3) * 4 + (RFIFOB(fd,4) >> 6);
+ y = ((RFIFOB(fd,4) & 0x3f) << 4) + (RFIFOB(fd,5) >> 4);
+ break;
+ case 15:
+ x = RFIFOB(fd,4) * 4 + (RFIFOB(fd,5) >> 6);
+ y = ((RFIFOB(fd,5) & 0x3f) << 4) + (RFIFOB(fd,6) >> 4);
+ break;
+ case 16:
+ x = RFIFOB(fd,10) * 4 + (RFIFOB(fd,11) >> 6);
+ y = ((RFIFOB(fd,11) & 0x3f) << 4) + (RFIFOB(fd,12) >> 4);
+ break;
+ default: // old version by default
+ x = RFIFOB(fd,2) * 4 + (RFIFOB(fd,3) >> 6);
+ y = ((RFIFOB(fd,3) & 0x3f) << 4) + (RFIFOB(fd,4) >> 4);
+ break;
+ }
}
pc_walktoxy(sd, x, y);
@@ -7527,28 +7821,39 @@ void clif_parse_GetCharNameRequest(int fd, struct map_session_data *sd) {
struct block_list *bl;
int account_id;
- switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
- case 8:
- account_id = RFIFOL(fd,11);
- break;
- case 9:
- account_id = RFIFOL(fd,8);
- break;
- case 10:
- account_id = RFIFOL(fd,10);
- break;
- case 11:
- account_id = RFIFOL(fd,6);
- break;
- case 12:
- account_id = RFIFOL(fd,11);
- break;
- case 13:
- account_id = RFIFOL(fd,6);
- break;
- default: // old version by default (+ packet version 6 and 7)
- account_id = RFIFOL(fd,2);
- break;
+ if (USE_PACKET_DB(sd)) {
+ account_id = RFIFOL(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0]);
+ } else {
+ switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ case 8:
+ account_id = RFIFOL(fd,11);
+ break;
+ case 9:
+ account_id = RFIFOL(fd,8);
+ break;
+ case 10:
+ account_id = RFIFOL(fd,10);
+ break;
+ case 11:
+ account_id = RFIFOL(fd,6);
+ break;
+ case 12:
+ account_id = RFIFOL(fd,11);
+ break;
+ case 13:
+ case 14:
+ account_id = RFIFOL(fd,6);
+ break;
+ case 15:
+ account_id = RFIFOL(fd,9);
+ break;
+ case 16:
+ account_id = RFIFOL(fd,4);
+ break;
+ default: // old version by default (+ packet version 6 and 7)
+ account_id = RFIFOL(fd,2);
+ break;
+ }
}
bl = map_id2bl(account_id);
if (bl == NULL)
@@ -7606,7 +7911,7 @@ void clif_parse_GetCharNameRequest(int fd, struct map_session_data *sd) {
nullpo_retv(md);
memcpy(WFIFOP(fd,6), md->name, 24);
- if (md->class >= 1285 && md->class <= 1288 && md->guild_id) {
+ if (md->class_ >= 1285 && md->class_ <= 1288 && md->guild_id) {
struct guild *g;
struct guild_castle *gc = guild_mapname2gc(map[md->bl.m].name);
if (gc && gc->guild_id > 0 && (g = guild_search(gc->guild_id)) != NULL) {
@@ -7620,7 +7925,7 @@ void clif_parse_GetCharNameRequest(int fd, struct map_session_data *sd) {
}
} else if (battle_config.show_mob_hp == 1) {
char mobhp[50];
- sprintf(mobhp, "hp: %d/%d", md->hp, mob_db[md->class].max_hp);
+ sprintf(mobhp, "hp: %d/%d", md->hp, mob_db[md->class_].max_hp);
WFIFOW(fd, 0) = 0x195;
memcpy(WFIFOP(fd,30), mobhp, 24);
WFIFOB(fd,54) = 0;
@@ -7644,42 +7949,47 @@ void clif_parse_GetCharNameRequest(int fd, struct map_session_data *sd) {
*/
void clif_parse_GlobalMessage(int fd, struct map_session_data *sd) { // S 008c <len>.w <str>.?B
char *message;
- char *buf;
+ unsigned char *buf;
nullpo_retv(sd);
- if (is_charcommand(fd, sd, RFIFOP(fd,4),0)!= CharCommand_None) return;
- if ((is_atcommand(fd, sd, RFIFOP(fd,4), 0) != AtCommand_None) ||
- (sd->sc_data &&
+ if ((is_atcommand(fd, sd, (char*)RFIFOP(fd,4), 0) != AtCommand_None) ||
+ (is_charcommand(fd, sd, (char*)RFIFOP(fd,4),0)!= CharCommand_None) ||
+ (sd->sc_data &&
(sd->sc_data[SC_BERSERK].timer != -1 || //ƒo[ƒT[ƒNŽž‚͉ï˜b‚à•s‰Â
sd->sc_data[SC_NOCHAT].timer != -1 ))) //ƒ`ƒƒƒbƒg‹ÖŽ~
return;
- message = (char*)aCalloc(RFIFOW(fd,2) + 128, sizeof(char));
- buf = (char*)aCalloc(RFIFOW(fd,2) + 4, sizeof(char));
+ message = (char*)aCallocA(RFIFOW(fd,2) + 128, sizeof(char));
+ buf = (unsigned char*)aCallocA(RFIFOW(fd,2) + 4, sizeof(char));
//printf("clif_parse_GlobalMessage: message: '%s'.\n", RFIFOP(fd,4));
- if (strncmp(RFIFOP(fd,4), sd->status.name, strlen(sd->status.name)) != 0) {
+ if (strncmp((char*)RFIFOP(fd,4), sd->status.name, strlen(sd->status.name)) != 0) {
printf("Hack on global message: character '%s' (account: %d), use an other name to send a (normal) message.\n", sd->status.name, sd->status.account_id);
// information is sended to all online GM
- sprintf(message, "Hack on global message (normal message): character '%s' (account: %d) uses an other name.", sd->status.name, sd->status.account_id);
- intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message, strlen(message) + 1);
- if (strlen(RFIFOP(fd,4)) == 0)
+ sprintf(message, "Hack on global message (normal message): character '%s' (account: %d) uses another name.", sd->status.name, sd->status.account_id);
+ intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message);
+ if (strlen((char*)RFIFOP(fd,4)) == 0)
strcpy(message, " This player sends a void name and a void message.");
else
sprintf(message, " This player sends (name:message): '%s'.", RFIFOP(fd,4));
- intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message, strlen(message) + 1);
+ intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message);
// message about the ban
if (battle_config.ban_spoof_namer > 0)
sprintf(message, " This player has been banned for %d minute(s).", battle_config.ban_spoof_namer);
else
sprintf(message, " This player hasn't been banned (Ban option is disabled).");
- intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message, strlen(message) + 1);
+ intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message);
// if we ban people
if (battle_config.ban_spoof_namer > 0) {
chrif_char_ask_name(-1, sd->status.name, 2, 0, 0, 0, 0, battle_config.ban_spoof_namer, 0); // type: 2 - ban (year, month, day, hour, minute, second)
clif_setwaitclose(fd); // forced to disconnect because of the hack
+
+ if(message) aFree(message);
+ if(buf) aFree(buf);
+
+ return;
}
// but for the hacker, we display on his screen (he see/look no difference).
} else {
@@ -7696,8 +8006,37 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data *sd) { // S 008c <
WFIFOW(fd,0) = 0x8e;
WFIFOSET(fd, WFIFOW(fd,2));
- if(message) free(message);
- if(buf) free(buf);
+#ifdef PCRE_SUPPORT
+ map_foreachinarea(npc_chat_sub, sd->bl.m, sd->bl.x-AREA_SIZE, sd->bl.y-AREA_SIZE, sd->bl.x+AREA_SIZE, sd->bl.y+AREA_SIZE, BL_NPC, RFIFOP(fd,4), strlen(RFIFOP(fd,4)), &sd->bl);
+#endif
+
+ // Celest
+ if (pc_calc_base_job2 (sd->status.class_) == 23 ) {
+ int next = pc_nextbaseexp(sd)>0 ? pc_nextbaseexp(sd) : sd->status.base_exp;
+ if (next > 0 && (sd->status.base_exp*100/next)%10 == 0) {
+ estr_lower((char*)RFIFOP(fd,4));
+ if (sd->state.snovice_flag == 0 && strstr((char*)RFIFOP(fd,4), msg_txt(504)))
+ sd->state.snovice_flag = 1;
+ else if (sd->state.snovice_flag == 1) {
+ sprintf(message, msg_txt(505), sd->status.name);
+ estr_lower(message);
+ if (strstr((char*)RFIFOP(fd,4), message))
+ sd->state.snovice_flag = 2;
+ }
+ else if (sd->state.snovice_flag == 2 && strstr((char*)RFIFOP(fd,4), msg_txt(506)))
+ sd->state.snovice_flag = 3;
+ else if (sd->state.snovice_flag == 3) {
+ int i;
+ status_change_start(&sd->bl,SkillStatusChangeTable[MO_EXPLOSIONSPIRITS],1,0,0,0,skill_get_time(MO_EXPLOSIONSPIRITS,1),0 );
+ for(i=0;i<5;i++)
+ pc_addspiritball(sd,skill_get_time(MO_CALLSPIRITS,1),5);
+ sd->state.snovice_flag = 0;
+ }
+ }
+ }
+
+ if(message) aFree(message);
+ if(buf) aFree(buf);
return;
}
@@ -7714,7 +8053,7 @@ int clif_message(struct block_list *bl, char* msg)
WBUFL(buf, 4) = bl->id;
memcpy(WBUFP(buf, 8), msg, msg_len);
- clif_send(buf, WBUFW(buf,2), bl, AREA);
+ clif_send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC); // by Gengar
return 0;
}
@@ -7725,17 +8064,20 @@ int clif_message(struct block_list *bl, char* msg)
*/
void clif_parse_MapMove(int fd, struct map_session_data *sd) {
// /m /mapmove (as @rura GM command)
- char output[100];
+ char output[30]; // 17+4+4=26, 30 max.
char map_name[17];
nullpo_retv(sd);
- memset(output, '\0', sizeof(output));
- memset(map_name, '\0', sizeof(map_name));
+// not needed at all as far as sprintf is used // [Ilpalazzo-sama]
+// memset(output, '\0', sizeof(output));
+// not needed -- map_name[16]='\0'; will do
+// memset(map_name, '\0', sizeof(map_name));
if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) &&
(pc_isGM(sd) >= get_atcommand_level(AtCommand_MapMove))) {
memcpy(map_name, RFIFOP(fd,2), 16);
+ map_name[16]='\0';
sprintf(output, "%s %d %d", map_name, RFIFOW(fd,18), RFIFOW(fd,20));
atcommand_rura(fd, sd, "@rura", output);
}
@@ -7747,58 +8089,89 @@ void clif_parse_MapMove(int fd, struct map_session_data *sd) {
*
*------------------------------------------
*/
-void clif_parse_ChangeDir(int fd, struct map_session_data *sd) {
+void clif_changed_dir(struct block_list *bl) {
unsigned char buf[64];
+ struct map_session_data *sd = NULL;
+
+ if (bl->type == BL_PC)
+ nullpo_retv (sd=(struct map_session_data *)bl);
+
+ WBUFW(buf,0) = 0x9c;
+ WBUFL(buf,2) = bl->id;
+ if (sd)
+ WBUFW(buf,6) = sd->head_dir;
+ WBUFB(buf,8) = status_get_dir(bl);
+ if (sd && sd->disguise > 23 && sd->disguise < 4001) // mob disguises [Valaris]
+ clif_send(buf, packet_len_table[0x9c], &sd->bl, AREA);
+ else
+ clif_send(buf, packet_len_table[0x9c], bl, AREA_WOS);
+
+ return;
+}
+
+/*==========================================
+ *
+ *------------------------------------------
+ */
+void clif_parse_ChangeDir(int fd, struct map_session_data *sd) {
short headdir, dir;
nullpo_retv(sd);
- switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
- case 7:
- headdir = RFIFOW(fd,5);
- dir = RFIFOB(fd,12);
- break;
- case 8:
- headdir = RFIFOW(fd,5);
- dir = RFIFOB(fd,12);
- break;
- case 9:
- headdir = RFIFOW(fd,7);
- dir = RFIFOB(fd,11);
- break;
- case 10:
- headdir = RFIFOW(fd,4);
- dir = RFIFOB(fd,9);
- break;
- case 11:
- headdir = RFIFOW(fd,8);
- dir = RFIFOB(fd,17);
- break;
- case 12:
- headdir = RFIFOW(fd,5);
- dir = RFIFOB(fd,12);
- break;
- case 13:
- headdir = RFIFOW(fd,6);
- dir = RFIFOB(fd,14);
- break;
- default: // old version by default (and packet version 6)
- headdir = RFIFOW(fd,2);
- dir = RFIFOB(fd,4);
- break;
+ if (USE_PACKET_DB(sd)) {
+ headdir = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0]);
+ dir = RFIFOB(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[1]);
+ } else {
+ switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ case 7:
+ headdir = RFIFOW(fd,5);
+ dir = RFIFOB(fd,12);
+ break;
+ case 8:
+ headdir = RFIFOW(fd,5);
+ dir = RFIFOB(fd,12);
+ break;
+ case 9:
+ headdir = RFIFOW(fd,7);
+ dir = RFIFOB(fd,11);
+ break;
+ case 10:
+ headdir = RFIFOW(fd,4);
+ dir = RFIFOB(fd,9);
+ break;
+ case 11:
+ headdir = RFIFOW(fd,8);
+ dir = RFIFOB(fd,17);
+ break;
+ case 12:
+ headdir = RFIFOW(fd,5);
+ dir = RFIFOB(fd,12);
+ break;
+ case 13:
+ case 14:
+ headdir = RFIFOW(fd,6);
+ dir = RFIFOB(fd,14);
+ break;
+ case 15:
+ headdir = RFIFOW(fd,3);
+ dir = RFIFOB(fd,7);
+ break;
+ case 16:
+ headdir = RFIFOW(fd,12);
+ dir = RFIFOB(fd,22);
+ break;
+
+ default: // old version by default (and packet version 6)
+ headdir = RFIFOW(fd,2);
+ dir = RFIFOB(fd,4);
+ break;
+ }
}
pc_setdir(sd, dir, headdir);
- WBUFW(buf,0) = 0x9c;
- WBUFL(buf,2) = sd->bl.id;
- WBUFW(buf,6) = headdir;
- WBUFB(buf,8) = dir;
- if (sd->disguise > 23 && sd->disguise < 4001) // mob disguises [Valaris]
- clif_send(buf, packet_len_table[0x9c], &sd->bl, AREA);
- else
- clif_send(buf, packet_len_table[0x9c], &sd->bl, AREA_WOS);
-
+ clif_changed_dir(&sd->bl);
+ return;
}
/*==========================================
@@ -7811,10 +8184,20 @@ void clif_parse_Emotion(int fd, struct map_session_data *sd) {
nullpo_retv(sd);
if (battle_config.basic_skill_check == 0 || pc_checkskill(sd, NV_BASIC) >= 2) {
+ if (RFIFOB(fd,2) == 34) {// prevent use of the mute emote [Valaris]
+ clif_skill_fail(sd, 1, 0, 1);
+ return;
+ }
+ // fix flood of emotion icon (ro-proxy): flood only the hacker player
+ if (sd->emotionlasttime >= time(NULL)) {
+ sd->emotionlasttime = time(NULL) + 2; // not more than 1 every 2 seconds (normal client is every 3-4 seconds)
+ clif_skill_fail(sd, 1, 0, 1);
+ return;
+ }
+ sd->emotionlasttime = time(NULL) + 2; // not more than 1 every 2 seconds (normal client is every 3-4 seconds)
+
WBUFW(buf,0) = 0xc0;
WBUFL(buf,2) = sd->bl.id;
- if(RFIFOB(fd,2)==34) // prevent use of the mute emote [Valaris]
- return;
WBUFB(buf,6) = RFIFOB(fd,2);
clif_send(buf, packet_len_table[0xc0], &sd->bl, AREA);
} else
@@ -7848,7 +8231,8 @@ void clif_parse_ActionRequest(int fd, struct map_session_data *sd) {
}
if (sd->npc_id != 0 || sd->opt1 > 0 || sd->status.option & 2 ||
(sd->sc_data &&
- (sd->sc_data[SC_AUTOCOUNTER].timer != -1 || //ƒI[ƒgƒJƒEƒ“ƒ^[
+ (sd->sc_data[SC_TRICKDEAD].timer != -1 ||
+ sd->sc_data[SC_AUTOCOUNTER].timer != -1 || //ƒI[ƒgƒJƒEƒ“ƒ^[
sd->sc_data[SC_BLADESTOP].timer != -1 || //”’nŽæ‚è
sd->sc_data[SC_DANCING].timer != -1))) //ƒ_ƒ“ƒX’†
return;
@@ -7858,35 +8242,50 @@ void clif_parse_ActionRequest(int fd, struct map_session_data *sd) {
pc_stop_walking(sd, 0);
pc_stopattack(sd);
- switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
- case 8:
- target_id = RFIFOL(fd,3);
- action_type = RFIFOB(fd,8);
- break;
- case 9:
- target_id = RFIFOL(fd,7);
- action_type = RFIFOB(fd,17);
- break;
- case 10:
- target_id = RFIFOL(fd,9);
- action_type = RFIFOB(fd,22);
- break;
- case 11:
- target_id = RFIFOL(fd,3);
- action_type = RFIFOB(fd,8);
- break;
- case 12:
- target_id = RFIFOL(fd,3);
- action_type = RFIFOB(fd,8);
- break;
- case 13:
- target_id = RFIFOL(fd,4);
- action_type = RFIFOB(fd,14);
- break;
- default: // old version by default (and packet version 6 and 7)
- target_id = RFIFOL(fd,2);
- action_type = RFIFOB(fd,6);
- break;
+ if (USE_PACKET_DB(sd)) {
+ target_id = RFIFOL(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0]);
+ action_type = RFIFOB(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[1]);
+ } else {
+ switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ case 8:
+ target_id = RFIFOL(fd,3);
+ action_type = RFIFOB(fd,8);
+ break;
+ case 9:
+ target_id = RFIFOL(fd,7);
+ action_type = RFIFOB(fd,17);
+ break;
+ case 10:
+ target_id = RFIFOL(fd,9);
+ action_type = RFIFOB(fd,22);
+ break;
+ case 11:
+ target_id = RFIFOL(fd,3);
+ action_type = RFIFOB(fd,8);
+ break;
+ case 12:
+ target_id = RFIFOL(fd,3);
+ action_type = RFIFOB(fd,8);
+ break;
+ case 13:
+ case 14:
+ target_id = RFIFOL(fd,4);
+ action_type = RFIFOB(fd,14);
+ break;
+ case 15:
+ target_id = RFIFOL(fd,6);
+ action_type = RFIFOB(fd,17);
+ break;
+ case 16:
+ target_id = RFIFOL(fd,9);
+ action_type = RFIFOB(fd,19);
+ break;
+
+ default: // old version by default (and packet version 6 and 7)
+ target_id = RFIFOL(fd,2);
+ action_type = RFIFOB(fd,6);
+ break;
+ }
}
switch(action_type) {
@@ -7911,15 +8310,15 @@ void clif_parse_ActionRequest(int fd, struct map_session_data *sd) {
case 0x02: // sitdown
if (battle_config.basic_skill_check == 0 || pc_checkskill(sd, NV_BASIC) >= 3) {
pc_stop_walking(sd, 1);
- skill_gangsterparadise(sd, 1); // ƒMƒƒƒ“ƒOƒXƒ^[ƒpƒ‰ƒ_ƒCƒXÝ’è
pc_setsit(sd);
+ skill_gangsterparadise(sd, 1); // ƒMƒƒƒ“ƒOƒXƒ^[ƒpƒ‰ƒ_ƒCƒXÝ’è fixed Valaris
clif_sitting(sd);
} else
clif_skill_fail(sd, 1, 0, 2);
break;
case 0x03: // standup
- skill_gangsterparadise(sd, 0); // ƒMƒƒƒ“ƒOƒXƒ^[ƒpƒ‰ƒ_ƒCƒX‰ðœ
pc_setstand(sd);
+ skill_gangsterparadise(sd, 0); // ƒMƒƒƒ“ƒOƒXƒ^[ƒpƒ‰ƒ_ƒCƒX‰ðœ fixed Valaris
WBUFW(buf, 0) = 0x8a;
WBUFL(buf, 2) = sd->bl.id;
WBUFB(buf,26) = 3;
@@ -7942,6 +8341,9 @@ void clif_parse_Restart(int fd, struct map_session_data *sd) {
pc_setrestartvalue(sd, 3);
pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, 2);
}
+ // in case the player's status somehow wasn't updated yet [Celest]
+ else if (sd->status.hp <= 0)
+ pc_setdead(sd);
break;
case 0x01:
if(!pc_isdead(sd) && (sd->opt1 || (sd->opt2 && !(night_flag == 1 && sd->opt2 == STATE_BLIND))))
@@ -7971,32 +8373,32 @@ void clif_parse_Wis(int fd, struct map_session_data *sd) { // S 0096 <len>.w <ni
//printf("clif_parse_Wis: message: '%s'.\n", RFIFOP(fd,28));
- gm_command = (char*)aCalloc(strlen(RFIFOP(fd,28)) + 28, sizeof(char)); // 24+3+(RFIFOW(fd,2)-28)+1 or 24+3+(strlen(RFIFOP(fd,28))+1 (size can be wrong with hacker)
+ gm_command = (char*)aCallocA(strlen((const char*)RFIFOP(fd,28)) + 28, sizeof(char)); // 24+3+(RFIFOW(fd,2)-28)+1 or 24+3+(strlen(RFIFOP(fd,28))+1 (size can be wrong with hacker)
sprintf(gm_command, "%s : %s", sd->status.name, RFIFOP(fd,28));
if ((is_charcommand(fd, sd, gm_command, 0) != CharCommand_None) ||
(is_atcommand(fd, sd, gm_command, 0) != AtCommand_None) ||
- (sd && sd->sc_data &&
+ (sd && sd->sc_data &&
(sd->sc_data[SC_BERSERK].timer!=-1 || //ƒo[ƒT[ƒNŽž‚͉ï˜b‚à•s‰Â
sd->sc_data[SC_NOCHAT].timer != -1))) //ƒ`ƒƒƒbƒg‹ÖŽ~
{
- if(gm_command) free(gm_command);
+ if(gm_command) aFree(gm_command);
return;
}
- if(gm_command) free(gm_command);
+ if(gm_command) aFree(gm_command);
// searching destination character
- dstsd = map_nick2sd(RFIFOP(fd,4));
+ dstsd = map_nick2sd((char*)RFIFOP(fd,4));
// player is not on this map-server
if (dstsd == NULL ||
// At this point, don't send wisp/page if it's not exactly the same name, because (example)
// if there are 'Test' player on an other map-server and 'test' player on this map-server,
// and if we ask for 'Test', we must not contact 'test' player
// so, we send information to inter-server, which is the only one which decide (and copy correct name).
- strcmp(dstsd->status.name, RFIFOP(fd,4)) != 0) // not exactly same name
+ strcmp(dstsd->status.name, (const char*)RFIFOP(fd,4)) != 0) // not exactly same name
// send message to inter-server
- intif_wis_message(sd, RFIFOP(fd,4), RFIFOP(fd,28), RFIFOW(fd,2)-28);
+ intif_wis_message(sd, (char*)RFIFOP(fd,4), (char*)RFIFOP(fd,28), RFIFOW(fd,2)-28);
// player is on this map-server
else {
// if you send to your self, don't send anything to others
@@ -8015,7 +8417,7 @@ void clif_parse_Wis(int fd, struct map_session_data *sd) { // S 0096 <len>.w <ni
}
// if source player not found in ignore list
if (i == MAX_IGNORE_LIST) {
- clif_wis_message(dstsd->fd, sd->status.name, RFIFOP(fd,28), RFIFOW(fd,2) - 28);
+ clif_wis_message(dstsd->fd, sd->status.name, (char*)RFIFOP(fd,28), RFIFOW(fd,2) - 28);
clif_wis_end(fd, 0); // type: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
}
}
@@ -8035,7 +8437,7 @@ void clif_parse_GMmessage(int fd, struct map_session_data *sd) {
if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) &&
(pc_isGM(sd) >= get_atcommand_level(AtCommand_Broadcast)))
- intif_GMmessage(RFIFOP(fd,4), RFIFOW(fd,2)-4, 0);
+ intif_GMmessage((char*)RFIFOP(fd,4), RFIFOW(fd,2)-4, 0);
}
/*==========================================
@@ -8048,31 +8450,42 @@ void clif_parse_TakeItem(int fd, struct map_session_data *sd) {
nullpo_retv(sd);
- switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
- case 7:
- map_object_id = RFIFOL(fd,6);
- break;
- case 8:
- map_object_id = RFIFOL(fd,6);
- break;
- case 9:
- map_object_id = RFIFOL(fd,9);
- break;
- case 10:
- map_object_id = RFIFOL(fd,7);
- break;
- case 11:
- map_object_id = RFIFOL(fd,10);
- break;
- case 12:
- map_object_id = RFIFOL(fd,6);
- break;
- case 13:
- map_object_id = RFIFOL(fd,5);
- break;
- default: // old version by default (and packet version 6)
- map_object_id = RFIFOL(fd,2);
- break;
+ if (USE_PACKET_DB(sd)) {
+ map_object_id = RFIFOL(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0]);
+ } else {
+ switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ case 7:
+ map_object_id = RFIFOL(fd,6);
+ break;
+ case 8:
+ map_object_id = RFIFOL(fd,6);
+ break;
+ case 9:
+ map_object_id = RFIFOL(fd,9);
+ break;
+ case 10:
+ map_object_id = RFIFOL(fd,7);
+ break;
+ case 11:
+ map_object_id = RFIFOL(fd,10);
+ break;
+ case 12:
+ map_object_id = RFIFOL(fd,6);
+ break;
+ case 13:
+ case 14:
+ map_object_id = RFIFOL(fd,5);
+ break;
+ case 15:
+ map_object_id = RFIFOL(fd,3);
+ break;
+ case 16:
+ map_object_id = RFIFOL(fd,5);
+ break;
+ default: // old version by default (and packet version 6)
+ map_object_id = RFIFOL(fd,2);
+ break;
+ }
}
fitem = (struct flooritem_data*)map_id2bl(map_object_id);
@@ -8113,35 +8526,49 @@ void clif_parse_DropItem(int fd, struct map_session_data *sd) {
sd->sc_data[SC_BERSERK].timer != -1)) ) //ƒo[ƒT[ƒN
return;
- switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
- case 8:
- item_index = RFIFOW(fd,5) - 2;
- item_amount = RFIFOW(fd,12);
- break;
- case 9:
- item_index = RFIFOW(fd,8) - 2;
- item_amount = RFIFOW(fd,15);
- break;
- case 10:
- item_index = RFIFOW(fd,6) - 2;
- item_amount = RFIFOW(fd,15);
- break;
- case 11:
- item_index = RFIFOW(fd,12) - 2;
- item_amount = RFIFOW(fd,17);
- break;
- case 12:
- item_index = RFIFOW(fd,5) - 2;
- item_amount = RFIFOW(fd,12);
- break;
- case 13:
- item_index = RFIFOW(fd,6) - 2;
- item_amount = RFIFOW(fd,10);
- break;
- default: // old version by default (+ packet version 6 and 7)
- item_index = RFIFOW(fd,2) - 2;
- item_amount = RFIFOW(fd,4);
- break;
+ if (USE_PACKET_DB(sd)) {
+ item_index = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0])-2;
+ item_amount = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[1]);
+ } else {
+ switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ case 8:
+ item_index = RFIFOW(fd,5) - 2;
+ item_amount = RFIFOW(fd,12);
+ break;
+ case 9:
+ item_index = RFIFOW(fd,8) - 2;
+ item_amount = RFIFOW(fd,15);
+ break;
+ case 10:
+ item_index = RFIFOW(fd,6) - 2;
+ item_amount = RFIFOW(fd,15);
+ break;
+ case 11:
+ item_index = RFIFOW(fd,12) - 2;
+ item_amount = RFIFOW(fd,17);
+ break;
+ case 12:
+ item_index = RFIFOW(fd,5) - 2;
+ item_amount = RFIFOW(fd,12);
+ break;
+ case 13:
+ case 14:
+ item_index = RFIFOW(fd,6) - 2;
+ item_amount = RFIFOW(fd,10);
+ break;
+ case 15:
+ item_index = RFIFOW(fd,4) - 2;
+ item_amount = RFIFOW(fd,10);
+ break;
+ case 16:
+ item_index = RFIFOW(fd,15) - 2;
+ item_amount = RFIFOW(fd,18);
+ break;
+ default: // old version by default (+ packet version 6 and 7)
+ item_index = RFIFOW(fd,2) - 2;
+ item_amount = RFIFOW(fd,4);
+ break;
+ }
}
pc_dropitem(sd, item_index, item_amount);
@@ -8158,7 +8585,7 @@ void clif_parse_UseItem(int fd, struct map_session_data *sd) {
clif_clearchar_area(&sd->bl, 1);
return;
}
- if (sd->npc_id!=0 || sd->vender_id != 0 || sd->opt1 > 0 ||
+ if (sd->npc_id!=0 || sd->vender_id != 0 || (sd->opt1 > 0 && sd->opt1 != 6) ||
(sd->sc_data && (sd->sc_data[SC_TRICKDEAD].timer != -1 || //Ž€‚ñ‚¾‚Ó‚è
sd->sc_data[SC_BLADESTOP].timer != -1 || //”’nŽæ‚è
sd->sc_data[SC_BERSERK].timer!=-1 || //ƒo[ƒT[ƒN
@@ -8168,34 +8595,45 @@ void clif_parse_UseItem(int fd, struct map_session_data *sd) {
if (sd->invincible_timer != -1)
pc_delinvincibletimer(sd);
- switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
- case 6:
- pc_useitem(sd,RFIFOW(fd,5)-2);
- break;
- case 7:
- pc_useitem(sd,RFIFOW(fd,6)-2);
- break;
- case 8:
- pc_useitem(sd,RFIFOW(fd,6)-2);
- break;
- case 9:
- pc_useitem(sd,RFIFOW(fd,9)-2);
- break;
- case 10:
- pc_useitem(sd,RFIFOW(fd,7)-2);
- break;
- case 11:
- pc_useitem(sd,RFIFOW(fd,10)-2);
- break;
- case 12:
- pc_useitem(sd,RFIFOW(fd,6)-2);
- break;
- case 13:
- pc_useitem(sd,RFIFOW(fd,5)-2);
- break;
- default: // old version by default
- pc_useitem(sd,RFIFOW(fd,2)-2);
- break;
+ if (USE_PACKET_DB(sd)) {
+ pc_useitem(sd,RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0])-2);
+ } else {
+ switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ case 6:
+ pc_useitem(sd,RFIFOW(fd,5)-2);
+ break;
+ case 7:
+ pc_useitem(sd,RFIFOW(fd,6)-2);
+ break;
+ case 8:
+ pc_useitem(sd,RFIFOW(fd,6)-2);
+ break;
+ case 9:
+ pc_useitem(sd,RFIFOW(fd,9)-2);
+ break;
+ case 10:
+ pc_useitem(sd,RFIFOW(fd,7)-2);
+ break;
+ case 11:
+ pc_useitem(sd,RFIFOW(fd,10)-2);
+ break;
+ case 12:
+ pc_useitem(sd,RFIFOW(fd,6)-2);
+ break;
+ case 13:
+ case 14:
+ pc_useitem(sd,RFIFOW(fd,5)-2);
+ break;
+ case 15:
+ pc_useitem(sd,RFIFOW(fd,3)-2);
+ break;
+ case 16:
+ pc_useitem(sd,RFIFOW(fd,5)-2);
+ break;
+ default: // old version by default
+ pc_useitem(sd,RFIFOW(fd,2)-2);
+ break;
+ }
}
}
@@ -8246,17 +8684,18 @@ void clif_parse_UnequipItem(int fd,struct map_session_data *sd)
clif_clearchar_area(&sd->bl,1);
return;
}
+ if(sd->npc_id!=0 || sd->vender_id != 0 || sd->opt1 > 0)
+ return;
index = RFIFOW(fd,2)-2;
- if(sd->status.inventory[index].attribute == 1 && sd->sc_data && sd->sc_data[SC_BROKNWEAPON].timer!=-1)
- skill_status_change_end(&sd->bl,SC_BROKNWEAPON,-1);
+
+ /*if(sd->status.inventory[index].attribute == 1 && sd->sc_data && sd->sc_data[SC_BROKNWEAPON].timer!=-1)
+ status_change_end(&sd->bl,SC_BROKNWEAPON,-1);
if(sd->status.inventory[index].attribute == 1 && sd->sc_data && sd->sc_data[SC_BROKNARMOR].timer!=-1)
- skill_status_change_end(&sd->bl,SC_BROKNARMOR,-1);
- if(sd->sc_data && ( sd->sc_data[SC_BLADESTOP].timer!=-1 || sd->sc_data[SC_BERSERK].timer!=-1 ))
- return;
+ status_change_end(&sd->bl,SC_BROKNARMOR,-1);
+ if(sd->sc_count && ( sd->sc_data[SC_BLADESTOP].timer!=-1 || sd->sc_data[SC_BERSERK].timer!=-1 ))
+ return;*/
- if(sd->npc_id!=0 || sd->vender_id != 0 || sd->opt1 > 0)
- return;
- pc_unequipitem(sd,index,0,BF_NORMAL);
+ pc_unequipitem(sd,index,1);
}
/*==========================================
@@ -8330,7 +8769,7 @@ void clif_parse_NpcSellListSend(int fd,struct map_session_data *sd)
void clif_parse_CreateChatRoom(int fd,struct map_session_data *sd)
{
if(battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_BASIC) >= 4){
- chat_createchat(sd,RFIFOW(fd,4),RFIFOB(fd,6),RFIFOP(fd,7),RFIFOP(fd,15),RFIFOW(fd,2)-15);
+ chat_createchat(sd,RFIFOW(fd,4),RFIFOB(fd,6),(char*)RFIFOP(fd,7),(char*)RFIFOP(fd,15),RFIFOW(fd,2)-15);
} else
clif_skill_fail(sd,1,0,3);
}
@@ -8341,7 +8780,7 @@ void clif_parse_CreateChatRoom(int fd,struct map_session_data *sd)
*/
void clif_parse_ChatAddMember(int fd,struct map_session_data *sd)
{
- chat_joinchat(sd,RFIFOL(fd,2),RFIFOP(fd,6));
+ chat_joinchat(sd,RFIFOL(fd,2),(char*)RFIFOP(fd,6));
}
/*==========================================
@@ -8350,7 +8789,7 @@ void clif_parse_ChatAddMember(int fd,struct map_session_data *sd)
*/
void clif_parse_ChatRoomStatusChange(int fd,struct map_session_data *sd)
{
- chat_changechatstatus(sd,RFIFOW(fd,4),RFIFOB(fd,6),RFIFOP(fd,7),RFIFOP(fd,15),RFIFOW(fd,2)-15);
+ chat_changechatstatus(sd,RFIFOW(fd,4),RFIFOB(fd,6),(char*)RFIFOP(fd,7),(char*)RFIFOP(fd,15),RFIFOW(fd,2)-15);
}
/*==========================================
@@ -8359,7 +8798,7 @@ void clif_parse_ChatRoomStatusChange(int fd,struct map_session_data *sd)
*/
void clif_parse_ChangeChatOwner(int fd,struct map_session_data *sd)
{
- chat_changechatowner(sd,RFIFOP(fd,6));
+ chat_changechatowner(sd,(char*)RFIFOP(fd,6));
}
/*==========================================
@@ -8368,7 +8807,7 @@ void clif_parse_ChangeChatOwner(int fd,struct map_session_data *sd)
*/
void clif_parse_KickFromChat(int fd,struct map_session_data *sd)
{
- chat_kickchat(sd,RFIFOP(fd,2));
+ chat_kickchat(sd,(char*)RFIFOP(fd,2));
}
/*==========================================
@@ -8429,7 +8868,7 @@ void clif_parse_TradeOk(int fd,struct map_session_data *sd)
* ŽæˆøƒLƒƒƒ“ƒZƒ‹
*------------------------------------------
*/
-void clif_parse_TradeCansel(int fd,struct map_session_data *sd)
+void clif_parse_TradeCancel(int fd,struct map_session_data *sd)
{
trade_tradecancel(sd);
}
@@ -8483,17 +8922,17 @@ void clif_parse_GetItemFromCart(int fd,struct map_session_data *sd)
void clif_parse_RemoveOption(int fd,struct map_session_data *sd)
{
if(pc_isriding(sd)) { // jobchange when removing peco [Valaris]
- if(sd->status.class==13)
- sd->status.class=sd->view_class=7;
+ if(sd->status.class_==13)
+ sd->status.class_=sd->view_class=7;
- if(sd->status.class==21)
- sd->status.class=sd->view_class=14;
+ if(sd->status.class_==21)
+ sd->status.class_=sd->view_class=14;
- if(sd->status.class==4014)
- sd->status.class=sd->view_class=4008;
+ if(sd->status.class_==4014)
+ sd->status.class_=sd->view_class=4008;
- if(sd->status.class==4022)
- sd->status.class=sd->view_class=4015;
+ if(sd->status.class_==4022)
+ sd->status.class_=sd->view_class=4015;
}
pc_setoption(sd,0);
@@ -8539,52 +8978,69 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) {
if (sd->chatID || sd->npc_id != 0 || sd->vender_id != 0)
return;
- switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
- case 6:
- skilllv = RFIFOW(fd,4);
- skillnum = RFIFOW(fd,9);
- target_id = RFIFOL(fd,11);
- break;
- case 7:
- skilllv = RFIFOW(fd,7);
- skillnum = RFIFOW(fd,9);
- target_id = RFIFOL(fd,15);
- break;
- case 8:
- skilllv = RFIFOW(fd,7);
- skillnum = RFIFOW(fd,12);
- target_id = RFIFOL(fd,16);
- break;
- case 9:
- skilllv = RFIFOW(fd,11);
- skillnum = RFIFOW(fd,18);
- target_id = RFIFOL(fd,22);
- break;
- case 10:
- skilllv = RFIFOW(fd,9);
- skillnum = RFIFOW(fd,15);
- target_id = RFIFOL(fd,18);
- break;
- case 11:
- skilllv = RFIFOW(fd,4);
- skillnum = RFIFOW(fd,7);
- target_id = RFIFOL(fd,10);
- break;
- case 12:
- skilllv = RFIFOW(fd,7);
- skillnum = RFIFOW(fd,12);
- target_id = RFIFOL(fd,16);
- break;
- case 13:
- skilllv = RFIFOW(fd,4);
- skillnum = RFIFOW(fd,10);
- target_id = RFIFOL(fd,22);
- break;
- default: // old version by default
- skilllv = RFIFOW(fd,2);
- skillnum = RFIFOW(fd,4);
- target_id = RFIFOL(fd,6);
- break;
+ if (USE_PACKET_DB(sd)) {
+ skilllv = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0]);
+ skillnum = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[1]);
+ target_id = RFIFOL(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[2]);
+ } else {
+ switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ case 6:
+ skilllv = RFIFOW(fd,4);
+ skillnum = RFIFOW(fd,9);
+ target_id = RFIFOL(fd,11);
+ break;
+ case 7:
+ skilllv = RFIFOW(fd,7);
+ skillnum = RFIFOW(fd,9);
+ target_id = RFIFOL(fd,15);
+ break;
+ case 8:
+ skilllv = RFIFOW(fd,7);
+ skillnum = RFIFOW(fd,12);
+ target_id = RFIFOL(fd,16);
+ break;
+ case 9:
+ skilllv = RFIFOW(fd,11);
+ skillnum = RFIFOW(fd,18);
+ target_id = RFIFOL(fd,22);
+ break;
+ case 10:
+ skilllv = RFIFOW(fd,9);
+ skillnum = RFIFOW(fd,15);
+ target_id = RFIFOL(fd,18);
+ break;
+ case 11:
+ skilllv = RFIFOW(fd,4);
+ skillnum = RFIFOW(fd,7);
+ target_id = RFIFOL(fd,10);
+ break;
+ case 12:
+ skilllv = RFIFOW(fd,7);
+ skillnum = RFIFOW(fd,12);
+ target_id = RFIFOL(fd,16);
+ break;
+ case 13:
+ case 14:
+ skilllv = RFIFOW(fd,4);
+ skillnum = RFIFOW(fd,10);
+ target_id = RFIFOL(fd,22);
+ break;
+ case 15:
+ skilllv = RFIFOW(fd,8);
+ skillnum = RFIFOW(fd,12);
+ target_id = RFIFOL(fd,18);
+ break;
+ case 16:
+ skilllv = RFIFOW(fd,8);
+ skillnum = RFIFOW(fd,16);
+ target_id = RFIFOL(fd,22);
+ break;
+ default: // old version by default
+ skilllv = RFIFOW(fd,2);
+ skillnum = RFIFOW(fd,4);
+ target_id = RFIFOL(fd,6);
+ break;
+ }
}
if (skillnotok(skillnum, sd))
@@ -8593,12 +9049,20 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) {
if (sd->skilltimer != -1) {
if (skillnum != SA_CASTCANCEL)
return;
- } else if (DIFF_TICK(tick, sd->canact_tick) < 0) {
+ } else if (DIFF_TICK(tick, sd->canact_tick) < 0 &&
+ // allow monk combos to ignore this delay [celest]
+ !(sd->sc_count && sd->sc_data[SC_COMBO].timer!=-1 &&
+ (skillnum == MO_EXTREMITYFIST ||
+ skillnum == MO_CHAINCOMBO ||
+ skillnum == MO_COMBOFINISH ||
+ skillnum == CH_PALMSTRIKE ||
+ skillnum == CH_TIGERFIST ||
+ skillnum == CH_CHAINCRUSH))) {
clif_skill_fail(sd, skillnum, 4, 0);
return;
}
- if ((sd->sc_data[SC_TRICKDEAD].timer != -1 && skillnum != NV_TRICKDEAD) ||
+ if ((sd->sc_data[SC_TRICKDEAD].timer != -1 && skillnum != NV_TRICKDEAD) ||
sd->sc_data[SC_BERSERK].timer != -1 || sd->sc_data[SC_NOCHAT].timer != -1 ||
sd->sc_data[SC_WEDDING].timer != -1 || sd->view_class == 22)
return;
@@ -8621,6 +9085,20 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) {
return;
}
}
+ } else if (skillnum == CH_TIGERFIST) {
+ if (sd->sc_data[SC_COMBO].timer == -1 || sd->sc_data[SC_COMBO].val1 != MO_COMBOFINISH) {
+ if (!sd->state.skill_flag ) {
+ sd->state.skill_flag = 1;
+ if (!sd->attacktarget) {
+ clif_skillinfo(sd, CH_TIGERFIST, 1, -2);
+ return;
+ } else
+ target_id = sd->attacktarget;
+ } else if (sd->bl.id == target_id) {
+ clif_skillinfo(sd, CH_TIGERFIST, 1, -2);
+ return;
+ }
+ }
}
if ((lv = pc_checkskill(sd, skillnum)) > 0) {
if (skilllv > lv)
@@ -8647,79 +9125,103 @@ void clif_parse_UseSkillToPos(int fd, struct map_session_data *sd) {
if(sd->chatID) return;
skillmoreinfo = -1;
- switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
- case 6:
- skilllv = RFIFOW(fd,4);
- skillnum = RFIFOW(fd,9);
- x = RFIFOW(fd,11);
- y = RFIFOW(fd,13);
- if (RFIFOW(fd,0) == 0x190)
- skillmoreinfo = 15;
- break;
- case 7:
- skilllv = RFIFOW(fd,7);
- skillnum = RFIFOW(fd,9);
- x = RFIFOW(fd,15);
- y = RFIFOW(fd,17);
- if (RFIFOW(fd,0) == 0x190)
- skillmoreinfo = 19;
- break;
- case 8:
- skilllv = RFIFOW(fd,3);
- skillnum = RFIFOW(fd,6);
- x = RFIFOW(fd,17);
- y = RFIFOW(fd,21);
- if (RFIFOW(fd,0) == 0x0a2)
- skillmoreinfo = 23;
- break;
- case 9:
- skilllv = RFIFOW(fd,5);
- skillnum = RFIFOW(fd,15);
- x = RFIFOW(fd,29);
- y = RFIFOW(fd,38);
- if (RFIFOW(fd,0) == 0x0a2)
- skillmoreinfo = 40;
- break;
- case 10:
- skilllv = RFIFOW(fd,10);
- skillnum = RFIFOW(fd,14);
- x = RFIFOW(fd,18);
- y = RFIFOW(fd,23);
- if (RFIFOW(fd,0) == 0x08c)
- skillmoreinfo = 25;
- break;
- case 11:
- skilllv = RFIFOW(fd,6); // 16? to check.
- skillnum = RFIFOW(fd,20);
- x = RFIFOW(fd,23);
- y = RFIFOW(fd,27);
- if (RFIFOW(fd,0) == 0x08c)
- skillmoreinfo = 29;
- break;
- case 12:
- skilllv = RFIFOW(fd,3); // 2? to check.
- skillnum = RFIFOW(fd,6);
- x = RFIFOW(fd,17);
- y = RFIFOW(fd,21);
- if (RFIFOW(fd,0) == 0x08c)
- skillmoreinfo = 23;
- break;
- case 13:
- skilllv = RFIFOW(fd,6);
- skillnum = RFIFOW(fd,9);
- x = RFIFOW(fd,23);
- y = RFIFOW(fd,26);
- if (RFIFOW(fd,0) == 0x08c)
- skillmoreinfo = 28;
- break;
- default: // old version by default
- skilllv = RFIFOW(fd,2);
- skillnum = RFIFOW(fd,4);
- x = RFIFOW(fd,6);
- y = RFIFOW(fd,8);
- if (RFIFOW(fd,0) == 0x190)
- skillmoreinfo = 10;
- break;
+ if (USE_PACKET_DB(sd)) {
+ skilllv = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0]);
+ skillnum = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[1]);
+ x = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[2]);
+ y = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[3]);
+ } else {
+ switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ case 6:
+ skilllv = RFIFOW(fd,4);
+ skillnum = RFIFOW(fd,9);
+ x = RFIFOW(fd,11);
+ y = RFIFOW(fd,13);
+ if (RFIFOW(fd,0) == 0x190)
+ skillmoreinfo = 15;
+ break;
+ case 7:
+ skilllv = RFIFOW(fd,7);
+ skillnum = RFIFOW(fd,9);
+ x = RFIFOW(fd,15);
+ y = RFIFOW(fd,17);
+ if (RFIFOW(fd,0) == 0x190)
+ skillmoreinfo = 19;
+ break;
+ case 8:
+ skilllv = RFIFOW(fd,3);
+ skillnum = RFIFOW(fd,6);
+ x = RFIFOW(fd,17);
+ y = RFIFOW(fd,21);
+ if (RFIFOW(fd,0) == 0x0a2)
+ skillmoreinfo = 23;
+ break;
+ case 9:
+ skilllv = RFIFOW(fd,5);
+ skillnum = RFIFOW(fd,15);
+ x = RFIFOW(fd,29);
+ y = RFIFOW(fd,38);
+ if (RFIFOW(fd,0) == 0x0a2)
+ skillmoreinfo = 40;
+ break;
+ case 10:
+ skilllv = RFIFOW(fd,10);
+ skillnum = RFIFOW(fd,14);
+ x = RFIFOW(fd,18);
+ y = RFIFOW(fd,23);
+ if (RFIFOW(fd,0) == 0x08c)
+ skillmoreinfo = 25;
+ break;
+ case 11:
+ skilllv = RFIFOW(fd,6); // 16? to check.
+ skillnum = RFIFOW(fd,20);
+ x = RFIFOW(fd,23);
+ y = RFIFOW(fd,27);
+ if (RFIFOW(fd,0) == 0x08c)
+ skillmoreinfo = 29;
+ break;
+ case 12:
+ skilllv = RFIFOW(fd,3); // 2? to check.
+ skillnum = RFIFOW(fd,6);
+ x = RFIFOW(fd,17);
+ y = RFIFOW(fd,21);
+ if (RFIFOW(fd,0) == 0x08c)
+ skillmoreinfo = 23;
+ break;
+ case 13:
+ case 14:
+ skilllv = RFIFOW(fd,6);
+ skillnum = RFIFOW(fd,9);
+ x = RFIFOW(fd,23);
+ y = RFIFOW(fd,26);
+ if (RFIFOW(fd,0) == 0x08c)
+ skillmoreinfo = 28;
+ break;
+ case 15:
+ skilllv = RFIFOW(fd,4);
+ skillnum = RFIFOW(fd,9);
+ x = RFIFOW(fd,22);
+ y = RFIFOW(fd,28);
+ if (RFIFOW(fd,0) == 0x113)
+ skillmoreinfo = 30;
+ break;
+ case 16:
+ skilllv = RFIFOW(fd,9);
+ skillnum = RFIFOW(fd,18);
+ x = RFIFOW(fd,22);
+ y = RFIFOW(fd,32);
+ if (RFIFOW(fd,0) == 0x07e)
+ skillmoreinfo = 34;
+ break;
+ default: // old version by default
+ skilllv = RFIFOW(fd,2);
+ skillnum = RFIFOW(fd,4);
+ x = RFIFOW(fd,6);
+ y = RFIFOW(fd,8);
+ if (RFIFOW(fd,0) == 0x190)
+ skillmoreinfo = 10;
+ break;
+ }
}
if (skillnotok(skillnum, sd))
@@ -8735,12 +9237,20 @@ void clif_parse_UseSkillToPos(int fd, struct map_session_data *sd) {
if (sd->skilltimer != -1)
return;
- else if (DIFF_TICK(tick, sd->canact_tick) < 0) {
+ else if (DIFF_TICK(tick, sd->canact_tick) < 0 &&
+ // allow monk combos to ignore this delay [celest]
+ !(sd->sc_count && sd->sc_data[SC_COMBO].timer!=-1 &&
+ (skillnum == MO_EXTREMITYFIST ||
+ skillnum == MO_CHAINCOMBO ||
+ skillnum == MO_COMBOFINISH ||
+ skillnum == CH_PALMSTRIKE ||
+ skillnum == CH_TIGERFIST ||
+ skillnum == CH_CHAINCRUSH))) {
clif_skill_fail(sd, skillnum, 4, 0);
return;
}
- if ((sd->sc_data[SC_TRICKDEAD].timer != -1 && skillnum != NV_TRICKDEAD) ||
+ if ((sd->sc_data[SC_TRICKDEAD].timer != -1 && skillnum != NV_TRICKDEAD) ||
sd->sc_data[SC_BERSERK].timer != -1 || sd->sc_data[SC_NOCHAT].timer != -1 ||
sd->sc_data[SC_WEDDING].timer != -1 || sd->view_class == 22)
return;
@@ -8770,7 +9280,7 @@ void clif_parse_UseSkillMap(int fd,struct map_session_data *sd)
if(sd->chatID) return;
- if (sd->npc_id!=0 || sd->vender_id != 0 || (sd->sc_data &&
+ if (sd->npc_id!=0 || sd->vender_id != 0 || (sd->sc_data &&
(sd->sc_data[SC_TRICKDEAD].timer != -1 ||
sd->sc_data[SC_BERSERK].timer!=-1 ||
sd->sc_data[SC_NOCHAT].timer!=-1 ||
@@ -8781,7 +9291,7 @@ void clif_parse_UseSkillMap(int fd,struct map_session_data *sd)
if(sd->invincible_timer != -1)
pc_delinvincibletimer(sd);
- skill_castend_map(sd,RFIFOW(fd,2),RFIFOP(fd,4));
+ skill_castend_map(sd,RFIFOW(fd,2),(char*)RFIFOP(fd,4));
}
/*==========================================
* ƒƒ‚—v‹
@@ -8854,7 +9364,7 @@ void clif_parse_NpcStringInput(int fd,struct map_session_data *sd)
memcpy(sd->npc_str,RFIFOP(fd,8),sizeof(sd->npc_str));
sd->npc_str[sizeof(sd->npc_str)-1]=0;
} else
- strcpy(sd->npc_str,RFIFOP(fd,8));
+ strcpy(sd->npc_str,(char*)RFIFOP(fd,8));
npc_scriptcont(sd,RFIFOL(fd,4));
}
@@ -8918,28 +9428,39 @@ void clif_parse_InsertCard(int fd,struct map_session_data *sd)
void clif_parse_SolveCharName(int fd, struct map_session_data *sd) {
int char_id;
- switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
- case 8:
- char_id = RFIFOL(fd,8);
- break;
- case 9:
- char_id = RFIFOL(fd,7);
- break;
- case 10:
- char_id = RFIFOL(fd,10);
- break;
- case 11:
- char_id = RFIFOL(fd,6);
- break;
- case 12:
- char_id = RFIFOL(fd,8);
- break;
- case 13:
- char_id = RFIFOL(fd,12);
- break;
- default: // old version by default (+ packet version 6 and 7)
- char_id = RFIFOL(fd,2);
- break;
+ if (USE_PACKET_DB(sd)) {
+ char_id = RFIFOL(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0]);
+ } else {
+ switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ case 8:
+ char_id = RFIFOL(fd,8);
+ break;
+ case 9:
+ char_id = RFIFOL(fd,7);
+ break;
+ case 10:
+ char_id = RFIFOL(fd,10);
+ break;
+ case 11:
+ char_id = RFIFOL(fd,6);
+ break;
+ case 12:
+ char_id = RFIFOL(fd,8);
+ break;
+ case 13:
+ case 14:
+ char_id = RFIFOL(fd,12);
+ break;
+ case 15:
+ char_id = RFIFOL(fd,10);
+ break;
+ case 16:
+ char_id = RFIFOL(fd,7);
+ break;
+ default: // old version by default (+ packet version 6 and 7)
+ char_id = RFIFOL(fd,2);
+ break;
+ }
}
clif_solved_charname(sd, char_id);
}
@@ -8951,15 +9472,14 @@ void clif_parse_SolveCharName(int fd, struct map_session_data *sd) {
void clif_parse_ResetChar(int fd, struct map_session_data *sd) {
nullpo_retv(sd);
- if (battle_config.atc_gmonly == 0 || pc_isGM(sd)) {
+ if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) &&
+ pc_isGM(sd) >= get_atcommand_level(AtCommand_ResetState)) {
switch(RFIFOW(fd,2)){
case 0:
- if (pc_isGM(sd) >= get_atcommand_level(AtCommand_ResetState))
- pc_resetstate(sd);
+ pc_resetstate(sd);
break;
case 1:
- if (pc_isGM(sd) >= get_atcommand_level(AtCommand_ResetState))
- pc_resetskill(sd);
+ pc_resetskill(sd);
break;
}
}
@@ -8970,7 +9490,7 @@ void clif_parse_ResetChar(int fd, struct map_session_data *sd) {
*------------------------------------------
*/
void clif_parse_LGMmessage(int fd, struct map_session_data *sd) {
- unsigned char buf[64];
+ unsigned char buf[512];
nullpo_retv(sd);
@@ -8995,42 +9515,55 @@ void clif_parse_MoveToKafra(int fd, struct map_session_data *sd) {
if (sd->npc_id != 0 || sd->vender_id != 0)
return;
- switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
- case 8:
- item_index = RFIFOW(fd,5) - 2;
- item_amount = RFIFOL(fd,12);
- break;
- case 9:
- item_index = RFIFOW(fd,5) - 2;
- item_amount = RFIFOL(fd,19);
- break;
- case 10:
- item_index = RFIFOW(fd,3) - 2;
- item_amount = RFIFOL(fd,15);
- break;
- case 11:
- item_index = RFIFOW(fd,6) - 2;
- item_amount = RFIFOL(fd,21);
- break;
- case 12:
- item_index = RFIFOW(fd,5) - 2;
- item_amount = RFIFOL(fd,12);
- break;
- case 13:
- item_index = RFIFOW(fd,6) - 2;
- item_amount = RFIFOL(fd,9);
- break;
- default: // old version by default (+ packet version 6 and 7)
- item_index = RFIFOW(fd,2) - 2;
- item_amount = RFIFOL(fd,4);
- break;
+ if (USE_PACKET_DB(sd)) {
+ item_index = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0])-2;
+ item_amount = RFIFOL(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[1]);
+ } else {
+ switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ case 8:
+ item_index = RFIFOW(fd,5) - 2;
+ item_amount = RFIFOL(fd,12);
+ break;
+ case 9:
+ item_index = RFIFOW(fd,5) - 2;
+ item_amount = RFIFOL(fd,19);
+ break;
+ case 10:
+ item_index = RFIFOW(fd,3) - 2;
+ item_amount = RFIFOL(fd,15);
+ break;
+ case 11:
+ item_index = RFIFOW(fd,6) - 2;
+ item_amount = RFIFOL(fd,21);
+ break;
+ case 12:
+ item_index = RFIFOW(fd,5) - 2;
+ item_amount = RFIFOL(fd,12);
+ break;
+ case 13:
+ case 14:
+ item_index = RFIFOW(fd,6) - 2;
+ item_amount = RFIFOL(fd,9);
+ break;
+ case 15:
+ item_index = RFIFOW(fd,4) - 2;
+ item_amount = RFIFOL(fd,10);
+ break;
+ case 16:
+ item_index = RFIFOW(fd,10) - 2;
+ item_amount = RFIFOL(fd,16);
+ break;
+ default: // old version by default (+ packet version 6 and 7)
+ item_index = RFIFOW(fd,2) - 2;
+ item_amount = RFIFOL(fd,4);
+ break;
+ }
}
if (item_index < 0 || item_index >= MAX_INVENTORY)
return;
if(itemdb_isdropable(sd->status.inventory[item_index].nameid) == 0)
-
return;
if (sd->state.storage_flag)
@@ -9048,35 +9581,49 @@ void clif_parse_MoveFromKafra(int fd,struct map_session_data *sd) {
nullpo_retv(sd);
- switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
- case 8:
- item_index = RFIFOW(fd,10) - 1;
- item_amount = RFIFOL(fd,22);
- break;
- case 9:
- item_index = RFIFOW(fd,11) - 1;
- item_amount = RFIFOL(fd,22);
- break;
- case 10:
- item_index = RFIFOW(fd,3) - 1;
- item_amount = RFIFOL(fd,13);
- break;
- case 11:
- item_index = RFIFOW(fd,4) - 1;
- item_amount = RFIFOL(fd,8);
- break;
- case 12:
- item_index = RFIFOW(fd,10) - 1;
- item_amount = RFIFOL(fd,22);
- break;
- case 13:
- item_index = RFIFOW(fd,12) - 1;
- item_amount = RFIFOL(fd,18);
- break;
- default: // old version by default (+ packet version 6 and 7)
- item_index = RFIFOW(fd,2) - 1;
- item_amount = RFIFOL(fd,4);
- break;
+ if (USE_PACKET_DB(sd)) {
+ item_index = RFIFOW(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[0])-1;
+ item_amount = RFIFOL(fd,packet_db[clif_config.packet_db_ver][RFIFOW(fd,0)].pos[1]);
+ } else {
+ switch (sd->packet_ver) { // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ case 8:
+ item_index = RFIFOW(fd,10) - 1;
+ item_amount = RFIFOL(fd,22);
+ break;
+ case 9:
+ item_index = RFIFOW(fd,11) - 1;
+ item_amount = RFIFOL(fd,22);
+ break;
+ case 10:
+ item_index = RFIFOW(fd,3) - 1;
+ item_amount = RFIFOL(fd,13);
+ break;
+ case 11:
+ item_index = RFIFOW(fd,4) - 1;
+ item_amount = RFIFOL(fd,8);
+ break;
+ case 12:
+ item_index = RFIFOW(fd,10) - 1;
+ item_amount = RFIFOL(fd,22);
+ break;
+ case 13:
+ case 14:
+ item_index = RFIFOW(fd,12) - 1;
+ item_amount = RFIFOL(fd,18);
+ break;
+ case 15:
+ item_index = RFIFOW(fd,4) - 1;
+ item_amount = RFIFOL(fd,17);
+ break;
+ case 16:
+ item_index = RFIFOW(fd,11) - 1;
+ item_amount = RFIFOL(fd,17);
+ break;
+ default: // old version by default (+ packet version 6 and 7)
+ item_index = RFIFOW(fd,2) - 1;
+ item_amount = RFIFOL(fd,4);
+ break;
+ }
}
if (sd->npc_id != 0 || sd->vender_id != 0)
@@ -9137,7 +9684,7 @@ void clif_parse_CloseKafra(int fd, struct map_session_data *sd) {
*/
void clif_parse_CreateParty(int fd, struct map_session_data *sd) {
if (battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_BASIC) >= 7) {
- party_create(sd,RFIFOP(fd,2));
+ party_create(sd,(char*)RFIFOP(fd,2),0,0);
} else
clif_skill_fail(sd,1,0,4);
}
@@ -9148,9 +9695,9 @@ void clif_parse_CreateParty(int fd, struct map_session_data *sd) {
*/
void clif_parse_CreateParty2(int fd, struct map_session_data *sd) {
if (battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_BASIC) >= 7){
- party_create(sd, RFIFOP(fd,2));
+ party_create(sd,(char*)RFIFOP(fd,2),RFIFOB(fd,26),RFIFOB(fd,27));
} else
- clif_skill_fail(sd, 1, 0, 4);
+ clif_skill_fail(sd,1,0,4);
}
/*==========================================
@@ -9187,7 +9734,7 @@ void clif_parse_LeaveParty(int fd, struct map_session_data *sd) {
*------------------------------------------
*/
void clif_parse_RemovePartyMember(int fd, struct map_session_data *sd) {
- party_removemember(sd,RFIFOL(fd,2),RFIFOP(fd,6));
+ party_removemember(sd,RFIFOL(fd,2),(char*)RFIFOP(fd,6));
}
/*==========================================
@@ -9204,16 +9751,15 @@ void clif_parse_PartyChangeOption(int fd, struct map_session_data *sd) {
*/
void clif_parse_PartyMessage(int fd, struct map_session_data *sd) {
nullpo_retv(sd);
- if (is_charcommand(fd, sd, RFIFOP(fd,4), 0) != CharCommand_None)
- return;
- if (is_atcommand(fd, sd, RFIFOP(fd,4), 0) != AtCommand_None)
- return;
- if(sd->sc_data &&
+
+ if (is_charcommand(fd, sd, (char*)RFIFOP(fd,4), 0) != CharCommand_None ||
+ is_atcommand(fd, sd, (char*)RFIFOP(fd,4), 0) != AtCommand_None ||
+ (sd->sc_data &&
(sd->sc_data[SC_BERSERK].timer!=-1 || //ƒo[ƒT[ƒNŽž‚͉ï˜b‚à•s‰Â
- sd->sc_data[SC_NOCHAT].timer!=-1)) //ƒ`ƒƒƒbƒg‹ÖŽ~
+ sd->sc_data[SC_NOCHAT].timer!=-1))) //ƒ`ƒƒƒbƒg‹ÖŽ~
return;
- party_send_message(sd, RFIFOP(fd,4), RFIFOW(fd,2)-4);
+ party_send_message(sd, (char*)RFIFOP(fd,4), RFIFOW(fd,2)-4);
}
/*==========================================
@@ -9249,32 +9795,7 @@ void clif_parse_PurchaseReq(int fd, struct map_session_data *sd) {
*------------------------------------------
*/
void clif_parse_OpenVending(int fd,struct map_session_data *sd) {
- vending_openvending(sd, RFIFOW(fd,2), RFIFOP(fd,4), RFIFOB(fd,84), RFIFOP(fd,85));
-}
-
-/*==========================================
- * /monster /item rewriten by [Yor]
- *------------------------------------------
- */
-void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd) {
- char monster_item_name[25];
-
- nullpo_retv(sd);
-
- memset(monster_item_name, '\0', sizeof(monster_item_name));
-
- if (battle_config.atc_gmonly == 0 || pc_isGM(sd)) {
- memcpy(monster_item_name, RFIFOP(fd,2), 24);
-
- if (mobdb_searchname(monster_item_name) != 0) {
- if (pc_isGM(sd) >= get_atcommand_level(AtCommand_Monster))
- atcommand_spawn(fd, sd, "@spawn", monster_item_name); // as @spawn
- } else if (itemdb_searchname(monster_item_name) != NULL) {
- if (pc_isGM(sd) >= get_atcommand_level(AtCommand_Item))
- atcommand_item(fd, sd, "@item", monster_item_name); // as @item
- }
-
- }
+ vending_openvending(sd, RFIFOW(fd,2), (char*)RFIFOP(fd,4), RFIFOB(fd,84), RFIFOP(fd,85));
}
/*==========================================
@@ -9282,7 +9803,7 @@ void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd) {
*------------------------------------------
*/
void clif_parse_CreateGuild(int fd,struct map_session_data *sd) {
- guild_create(sd, RFIFOP(fd,6));
+ guild_create(sd, (char*)RFIFOP(fd,6));
}
/*==========================================
@@ -9297,7 +9818,7 @@ void clif_parse_GuildCheckMaster(int fd, struct map_session_data *sd) {
* ƒMƒ‹ƒhî•ñ—v‹
*------------------------------------------
*/
-void clif_parse_GuildReqeustInfo(int fd, struct map_session_data *sd) {
+void clif_parse_GuildRequestInfo(int fd, struct map_session_data *sd) {
switch(RFIFOL(fd,2)){
case 0: // ƒMƒ‹ƒhŠî–{î•ñA“¯–¿“G‘Îî•ñ
clif_guild_basicinfo(sd);
@@ -9332,7 +9853,7 @@ void clif_parse_GuildChangePositionInfo(int fd, struct map_session_data *sd) {
int i;
for(i = 4; i < RFIFOW(fd,2); i += 40 ){
- guild_change_position(sd, RFIFOL(fd,i), RFIFOL(fd,i+4), RFIFOL(fd,i+12), RFIFOP(fd,i+16));
+ guild_change_position(sd, RFIFOL(fd,i), RFIFOL(fd,i+4), RFIFOL(fd,i+12), (char*)RFIFOP(fd,i+16));
}
}
@@ -9366,7 +9887,7 @@ void clif_parse_GuildRequestEmblem(int fd,struct map_session_data *sd) {
*------------------------------------------
*/
void clif_parse_GuildChangeEmblem(int fd,struct map_session_data *sd) {
- guild_change_emblem(sd,RFIFOW(fd,2)-4,RFIFOP(fd,4));
+ guild_change_emblem(sd,RFIFOW(fd,2)-4,(char*)RFIFOP(fd,4));
}
/*==========================================
@@ -9374,7 +9895,7 @@ void clif_parse_GuildChangeEmblem(int fd,struct map_session_data *sd) {
*------------------------------------------
*/
void clif_parse_GuildChangeNotice(int fd,struct map_session_data *sd) {
- guild_change_notice(sd,RFIFOL(fd,2),RFIFOP(fd,6),RFIFOP(fd,66));
+ guild_change_notice(sd,RFIFOL(fd,2),(char*)RFIFOP(fd,6),(char*)RFIFOP(fd,66));
}
/*==========================================
@@ -9398,7 +9919,7 @@ void clif_parse_GuildReplyInvite(int fd,struct map_session_data *sd) {
*------------------------------------------
*/
void clif_parse_GuildLeave(int fd,struct map_session_data *sd) {
- guild_leave(sd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOP(fd,14));
+ guild_leave(sd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),(char*)RFIFOP(fd,14));
}
/*==========================================
@@ -9406,7 +9927,7 @@ void clif_parse_GuildLeave(int fd,struct map_session_data *sd) {
*------------------------------------------
*/
void clif_parse_GuildExplusion(int fd,struct map_session_data *sd) {
- guild_explusion(sd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOP(fd,14));
+ guild_explusion(sd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),(char*)RFIFOP(fd,14));
}
/*==========================================
@@ -9415,16 +9936,15 @@ void clif_parse_GuildExplusion(int fd,struct map_session_data *sd) {
*/
void clif_parse_GuildMessage(int fd,struct map_session_data *sd) {
nullpo_retv(sd);
- if (is_charcommand(fd, sd, RFIFOP(fd, 4), 0) != CharCommand_None)
- return;
- if (is_atcommand(fd, sd, RFIFOP(fd, 4), 0) != AtCommand_None)
- return;
- if(sd->sc_data &&
+
+ if (is_charcommand(fd, sd, (char*)RFIFOP(fd, 4), 0) != CharCommand_None ||
+ is_atcommand(fd, sd, (char*)RFIFOP(fd, 4), 0) != AtCommand_None ||
+ (sd->sc_data &&
(sd->sc_data[SC_BERSERK].timer!=-1 || //ƒo[ƒT[ƒNŽž‚͉ï˜b‚à•s‰Â
- sd->sc_data[SC_NOCHAT].timer!=-1)) //ƒ`ƒƒƒbƒg‹ÖŽ~
+ sd->sc_data[SC_NOCHAT].timer!=-1))) //ƒ`ƒƒƒbƒg‹ÖŽ~
return;
- guild_send_message(sd, RFIFOP(fd,4), RFIFOW(fd,2)-4);
+ guild_send_message(sd, (char*)RFIFOP(fd,4), RFIFOW(fd,2)-4);
}
/*==========================================
@@ -9464,7 +9984,7 @@ void clif_parse_GuildOpposition(int fd, struct map_session_data *sd) {
*------------------------------------------
*/
void clif_parse_GuildBreak(int fd, struct map_session_data *sd) {
- guild_break(sd,RFIFOP(fd,2));
+ guild_break(sd,(char*)RFIFOP(fd,2));
}
// pet
@@ -9488,7 +10008,7 @@ void clif_parse_SendEmotion(int fd, struct map_session_data *sd) {
}
void clif_parse_ChangePetName(int fd, struct map_session_data *sd) {
- pet_change_name(sd,RFIFOP(fd,2));
+ pet_change_name(sd,(char*)RFIFOP(fd,2));
}
// Kick (right click menu for GM "(name) force to quit")
@@ -9559,6 +10079,31 @@ void clif_parse_Recall(int fd, struct map_session_data *sd) { // Added by RoVeRT
return;
}
+/*==========================================
+ * /monster /item rewriten by [Yor]
+ *------------------------------------------
+ */
+void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd) {
+ char monster_item_name[25];
+
+ nullpo_retv(sd);
+
+ memset(monster_item_name, '\0', sizeof(monster_item_name));
+
+ if (battle_config.atc_gmonly == 0 || pc_isGM(sd)) {
+ memcpy(monster_item_name, RFIFOP(fd,2), 24);
+
+ if (mobdb_searchname(monster_item_name) != 0) {
+ if (pc_isGM(sd) >= get_atcommand_level(AtCommand_Monster))
+ atcommand_spawn(fd, sd, "@spawn", monster_item_name); // as @spawn
+ } else if (itemdb_searchname(monster_item_name) != NULL) {
+ if (pc_isGM(sd) >= get_atcommand_level(AtCommand_Item))
+ atcommand_item(fd, sd, "@item", monster_item_name); // as @item
+ }
+
+ }
+}
+
void clif_parse_GMHide(int fd, struct map_session_data *sd) { // Modified by [Yor]
nullpo_retv(sd);
@@ -9607,10 +10152,10 @@ void clif_parse_GMReqNoChat(int fd,struct map_session_data *sd)
WFIFOSET(dstfd,packet_len_table[0x14b]);
dstsd->status.manner -= limit;
if(dstsd->status.manner < 0)
- skill_status_change_start(bl,SC_NOCHAT,0,0,0,0,0,0);
+ status_change_start(bl,SC_NOCHAT,0,0,0,0,0,0);
else{
dstsd->status.manner = 0;
- skill_status_change_end(bl,SC_NOCHAT,-1);
+ status_change_end(bl,SC_NOCHAT,-1);
}
printf("name:%s type:%d limit:%d manner:%d\n",dstsd->status.name,type,limit,dstsd->status.manner);
}
@@ -9628,7 +10173,7 @@ void clif_parse_GMReqNoChatCount(int fd, struct map_session_data *sd)
WFIFOW(fd,0) = 0x1e0;
WFIFOL(fd,2) = tid;
- sprintf(WFIFOP(fd,6),"%d",tid);
+ sprintf((char*)WFIFOP(fd,6),"%d",tid);
// memcpy(WFIFOP(fd,6), "TESTNAME", 24);
WFIFOSET(fd, packet_len_table[0x1e0]);
@@ -9642,14 +10187,14 @@ void clif_parse_PMIgnore(int fd, struct map_session_data *sd) { // Rewritten by
memset(output, '\0', sizeof(output));
- nick = RFIFOP(fd,2); // speed up
+ nick = (char*)RFIFOP(fd,2); // speed up
RFIFOB(fd,25) = '\0'; // to be sure that the player name have at maximum 23 characters
//printf("Ignore: char '%s' state: %d\n", nick, RFIFOB(fd,26));
WFIFOW(fd,0) = 0x0d1; // R 00d1 <type>.B <fail>.B: type: 0: deny, 1: allow, fail: 0: success, 1: fail
WFIFOB(fd,2) = RFIFOB(fd,26);
// do nothing only if nick can not exist
- if (strlen(nick) < 4) {
+ if (strlen(nick) < 4) {
WFIFOB(fd,3) = 1; // fail
WFIFOSET(fd, packet_len_table[0x0d1]);
if (RFIFOB(fd,26) == 0) // type
@@ -9669,7 +10214,7 @@ void clif_parse_PMIgnore(int fd, struct map_session_data *sd) { // Rewritten by
clif_wis_message(fd, wisp_server_name, "This player is already blocked.", strlen("This player is already blocked.") + 1);
if (strcmp(wisp_server_name, nick) == 0) { // to found possible bot users who automaticaly ignore people.
sprintf(output, "Character '%s' (account: %d) has tried AGAIN to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name);
- intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output, strlen(output) + 1);
+ intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output);
}
return;
} else if (pos == -1 && sd->ignore[i].name[0] == '\0')
@@ -9682,7 +10227,7 @@ void clif_parse_PMIgnore(int fd, struct map_session_data *sd) { // Rewritten by
WFIFOSET(fd, packet_len_table[0x0d1]);
if (strcmp(wisp_server_name, nick) == 0) { // to found possible bot users who automaticaly ignore people.
sprintf(output, "Character '%s' (account: %d) has tried to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name);
- intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output, strlen(output) + 1);
+ intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output);
// send something to be inform and force bot to ignore twice... If GM receiving block + block again, it's a bot :)
clif_wis_message(fd, wisp_server_name, "Add me in your ignore list, doesn't block my wisps.", strlen("Add me in your ignore list, doesn't block my wisps.") + 1);
}
@@ -9692,7 +10237,7 @@ void clif_parse_PMIgnore(int fd, struct map_session_data *sd) { // Rewritten by
clif_wis_message(fd, wisp_server_name, "You can not block more people.", strlen("You can not block more people.") + 1);
if (strcmp(wisp_server_name, nick) == 0) { // to found possible bot users who automaticaly ignore people.
sprintf(output, "Character '%s' (account: %d) has tried to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name);
- intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output, strlen(output) + 1);
+ intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output);
}
}
// allow action (we remove all same nicks if they exist)
@@ -9701,7 +10246,7 @@ void clif_parse_PMIgnore(int fd, struct map_session_data *sd) { // Rewritten by
for(i = 0; i < MAX_IGNORE_LIST; i++)
if (strcmp(sd->ignore[i].name, nick) == 0) {
memset(sd->ignore[i].name, 0, sizeof(sd->ignore[i].name));
- if (pos != -1) {
+ if (pos == -1) {
WFIFOB(fd,3) = 0; // success
WFIFOSET(fd, packet_len_table[0x0d1]);
pos = i; // don't break, to remove ALL same nick
@@ -9753,6 +10298,38 @@ void clif_parse_PMIgnoreAll(int fd, struct map_session_data *sd) { // Rewritten
return;
}
+/*==========================================
+ * Wis‹‘”ÛƒŠƒXƒg
+ *------------------------------------------
+ */
+ int pstrcmp(const void *a, const void *b)
+{
+ return strcmp((char *)a, (char *)b);
+}
+void clif_parse_PMIgnoreList(int fd,struct map_session_data *sd)
+{
+ int i,j=0,count=0;
+
+ qsort (sd->ignore[0].name, MAX_IGNORE_LIST, sizeof(sd->ignore[0].name), pstrcmp);
+ for(i = 0; i < MAX_IGNORE_LIST; i++){ //’†g‚ª‚ ‚é‚̂𔂦‚é
+ if(sd->ignore[i].name[0] != 0)
+ count++;
+ }
+ WFIFOW(fd,0) = 0xd4;
+ WFIFOW(fd,2) = 4 + (24 * count);
+ for(i = 0; i < MAX_IGNORE_LIST; i++){
+ if(sd->ignore[i].name[0] != 0){
+ memcpy(WFIFOP(fd, 4 + j * 24),sd->ignore[i].name, 24);
+ j++;
+ }
+ }
+ WFIFOSET(fd, WFIFOW(fd,2));
+ if(count >= MAX_IGNORE_LIST) //–žƒ^ƒ“‚È‚çÅŒã‚Ì1ŒÂ‚ðÁ‚·
+ sd->ignore[MAX_IGNORE_LIST - 1].name[0] = 0;
+
+ return;
+}
+
void clif_parse_skillMessage(int fd, struct map_session_data *sd) { // Added by RoVeRT
int skillid,skilllv, x, y;
char *mes;
@@ -9763,7 +10340,7 @@ void clif_parse_skillMessage(int fd, struct map_session_data *sd) { // Added by
y = RFIFOB(fd,6);
x = RFIFOB(fd,8);
- mes = RFIFOP(fd,10);
+ mes = (char*)RFIFOP(fd,10);
// skill 220 = graffiti
// printf("skill: %d %d location: %3d %3d message: %s\n", skillid, skilllv, x, y, (char*)mes);
@@ -9795,11 +10372,11 @@ void clif_parse_sn_doridori(int fd, struct map_session_data *sd) {
* ƒXƒpƒmƒr‚Ì”š—ô”g“®
*------------------------------------------
*/
-void clif_parse_sn_explosionspirits(int fd, struct map_session_data *sd)
+void clif_parse_sn_explosionspirits(int fd, struct map_session_data *sd)
{
if(sd){
int nextbaseexp=pc_nextbaseexp(sd);
- struct pc_base_job s_class = pc_calc_base_job(sd->status.class);
+ struct pc_base_job s_class = pc_calc_base_job(sd->status.class_);
if (battle_config.etc_log){
if(nextbaseexp != 0)
printf("SuperNovice explosionspirits!! %d %d %d %d\n",sd->bl.id,s_class.job,sd->status.base_exp,(int)((double)1000*sd->status.base_exp/nextbaseexp));
@@ -9808,7 +10385,7 @@ void clif_parse_sn_explosionspirits(int fd, struct map_session_data *sd)
}
if(s_class.job == 23 && sd->status.base_exp > 0 && nextbaseexp > 0 && (int)((double)1000*sd->status.base_exp/nextbaseexp)%100==0){
clif_skill_nodamage(&sd->bl,&sd->bl,MO_EXPLOSIONSPIRITS,5,1);
- skill_status_change_start(&sd->bl,SkillStatusChangeTable[MO_EXPLOSIONSPIRITS],5,0,0,0,skill_get_time(MO_EXPLOSIONSPIRITS,5),0 );
+ status_change_start(&sd->bl,SkillStatusChangeTable[MO_EXPLOSIONSPIRITS],5,0,0,0,skill_get_time(MO_EXPLOSIONSPIRITS,5),0 );
}
}
return;
@@ -9839,7 +10416,7 @@ void clif_parse_friends_list_add(int fd, struct map_session_data *sd) {
struct map_session_data *f_sd;
int i;
- f_sd = map_nick2sd(RFIFOP(fd,2));
+ f_sd = map_nick2sd((char*)RFIFOP(fd,2));
// Friend doesn't exist (no player with this name)
if (f_sd == NULL) {
@@ -9917,9 +10494,28 @@ void clif_parse_GMkillall(int fd,struct map_session_data *sd)
return;
}
+/*==========================================
+ * ƒpƒPƒbƒgƒfƒoƒbƒO
+ *------------------------------------------
+ */
+void clif_parse_debug(int fd,struct map_session_data *sd)
+{
+ int i, cmd;
+
+ cmd = RFIFOW(fd,0);
+
+ printf("packet debug 0x%4X\n",cmd);
+ printf("---- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F");
+ for(i=0;i<packet_db[sd->packet_ver][cmd].len;i++){
+ if((i&15)==0)
+ printf("\n%04X ",i);
+ printf("%02X ",RFIFOB(fd,i));
+ }
+ printf("\n");
+}
+
// functions list
-static void (*clif_parse_func_table[7][0x220])() = {
- {
+static void (*clif_parse_func_table[MAX_PACKET_DB])(int, struct map_session_data *) = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -9951,11 +10547,11 @@ static void (*clif_parse_func_table[7][0x220])() = {
NULL, clif_parse_HowManyConnections, NULL, NULL, NULL, clif_parse_NpcBuySellSelected, NULL, NULL,
clif_parse_NpcBuyListSend, clif_parse_NpcSellListSend, NULL, NULL, clif_parse_GMKick, NULL, clif_parse_GMkillall, clif_parse_PMIgnore,
// d0
- clif_parse_PMIgnoreAll, NULL, NULL, NULL, NULL, clif_parse_CreateChatRoom, NULL, NULL,
+ clif_parse_PMIgnoreAll, NULL, NULL, clif_parse_PMIgnoreList, NULL, clif_parse_CreateChatRoom, NULL, NULL,
NULL, clif_parse_ChatAddMember, NULL, NULL, NULL, NULL, clif_parse_ChatRoomStatusChange, NULL,
// e0
clif_parse_ChangeChatOwner, NULL, clif_parse_KickFromChat, clif_parse_ChatLeave, clif_parse_TradeRequest, NULL, clif_parse_TradeAck, NULL,
- clif_parse_TradeAddItem, NULL, NULL, clif_parse_TradeOk, NULL, clif_parse_TradeCansel, NULL, clif_parse_TradeCommit,
+ clif_parse_TradeAddItem, NULL, NULL, clif_parse_TradeOk, NULL, clif_parse_TradeCancel, NULL, clif_parse_TradeCommit,
// f0
NULL, NULL, NULL, clif_parse_MoveToKafra, NULL, clif_parse_MoveFromKafra, NULL, clif_parse_CloseKafra,
NULL, clif_parse_CreateParty, NULL, NULL, clif_parse_PartyInvite, NULL, NULL, clif_parse_ReplyPartyInvite,
@@ -9975,7 +10571,7 @@ static void (*clif_parse_func_table[7][0x220])() = {
// 140
clif_parse_MapMove, NULL, NULL, clif_parse_NpcAmountInput, NULL, NULL, clif_parse_NpcCloseClicked, NULL,
- NULL, clif_parse_GMReqNoChat, NULL, NULL, NULL, clif_parse_GuildCheckMaster, NULL, clif_parse_GuildReqeustInfo,
+ NULL, clif_parse_GMReqNoChat, NULL, NULL, NULL, clif_parse_GuildCheckMaster, NULL, clif_parse_GuildRequestInfo,
// 150
NULL, clif_parse_GuildRequestEmblem, NULL, clif_parse_GuildChangeEmblem, NULL, clif_parse_GuildChangeMemberPosition, NULL, NULL,
NULL, clif_parse_GuildLeave, NULL, clif_parse_GuildExplusion, NULL, clif_parse_GuildBreak, NULL, NULL,
@@ -10010,7 +10606,8 @@ static void (*clif_parse_func_table[7][0x220])() = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, clif_parse_sn_doridori,
clif_parse_CreateParty2, NULL, NULL, NULL, NULL, clif_parse_sn_explosionspirits, NULL, NULL,
// 1f0
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, clif_parse_ReqAdopt,
+ NULL, NULL, NULL, NULL, NULL, NULL,
// 200
NULL, NULL, clif_parse_friends_list_add, clif_parse_friends_list_remove, NULL, NULL, NULL, NULL,
@@ -10020,13 +10617,6 @@ static void (*clif_parse_func_table[7][0x220])() = {
#if 0
case 0xd3: clif_parse_IgnoreList
#endif
- },
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL}
};
/*==========================================
@@ -10035,28 +10625,33 @@ static void (*clif_parse_func_table[7][0x220])() = {
*------------------------------------------
*/
static int clif_parse(int fd) {
- int packet_len = 0, cmd, packet_ver;
+ int packet_len = 0, cmd, packet_ver, dump = 0;
struct map_session_data *sd;
- sd = session[fd]->session_data;
+ sd = (struct map_session_data*)session[fd]->session_data;
// Ú‘±‚ªØ‚ê‚Ä‚é‚̂ŌãŽn––
if (!chrif_isconnect() || session[fd]->eof) { // charŽI‚ÉŒq‚ª‚Á‚ĂȂ¢ŠÔ‚ÍÚ‘±‹ÖŽ~ (!chrif_isconnect())
if (sd && sd->state.auth) {
- if (chrif_isconnect())
- clif_quitsave(fd, sd);
+ clif_quitsave(fd, sd); // the function doesn't send to inter-server/char-server if it is not connected [Yor]
if (sd->status.name != NULL)
- printf("Player [%s] has logged off your server.\n", sd->status.name); // Player logout display [Valaris]
+ sprintf(tmp_output,"%sCharacter '"CL_WHITE"%s"CL_RESET"' logged off.\n", (pc_isGM(sd))?"GM ":"",sd->status.name); // Player logout display [Valaris]
else
- printf("Player with account [%d] has logged off your server.\n", sd->bl.id); // Player logout display [Yor]
+ sprintf(tmp_output,"%sCharacter with Account ID '"CL_WHITE"%d"CL_RESET"' logged off.\n", (pc_isGM(sd))?"GM ":"", sd->bl.id); // Player logout display [Yor]
} else if (sd) { // not authentified! (refused by char-server or disconnect before to be authentified)
- printf("Player with account [%d] has logged off your server (not auth account).\n", sd->bl.id); // Player logout display [Yor]
- map_deliddb(&sd->bl); // account_id has been included in the DB before auth answer
+ sprintf(tmp_output,"Player not authenticated with Account ID '"CL_WHITE"%d"CL_RESET"' logged off.\n", sd->bl.id); // Player logout display [Yor]
+// if (chrif_isconnect())
+// clif_quitsave(fd, sd);
+ map_deliddb(&sd->bl); // account_id has been included in the DB before auth answer [Yor]
+// sd = 0;
+ } else {
+ unsigned char *ip = (unsigned char *) &session[fd]->client_addr.sin_addr;
+ sprintf(tmp_output,"Player not identified with IP '"CL_WHITE"%d.%d.%d.%d"CL_RESET"' logged off.\n", ip[0],ip[1],ip[2],ip[3]);
}
+ ShowInfo(tmp_output);
close(fd);
- if (sd) // ’ljÁ
-
- map_deliddb(&sd->bl); // ’ljÁ
+// if (sd) // ’ljÁ
+// map_deliddb(&sd->bl); // ’ljÁ
delete_session(fd);
return 0;
}
@@ -10064,7 +10659,7 @@ static int clif_parse(int fd) {
if (RFIFOREST(fd) < 2)
return 0;
- //printf("clif_parse: connection #%d, packet: 0x%x (with being read: %d bytes).\n", fd, RFIFOW(fd,0), RFIFOREST(fd));
+// printf("clif_parse: connection #%d, packet: 0x%x (with being read: %d bytes).\n", fd, RFIFOW(fd,0), RFIFOREST(fd));
cmd = RFIFOW(fd,0);
@@ -10084,7 +10679,8 @@ static int clif_parse(int fd) {
RFIFOSKIP(fd,2);
break;
case 0x7532: // Ú‘±‚ÌØ’f
- session[fd]->eof = 1;
+ close(fd);
+ session[fd]->eof=1;
break;
}
return 0;
@@ -10092,119 +10688,135 @@ static int clif_parse(int fd) {
// get packet version before to parse
packet_ver = 0;
- if (sd)
+ if (sd) {
packet_ver = sd->packet_ver;
+ if (packet_ver < 0 || packet_ver > MAX_PACKET_VER) { // unusual, but just in case
+ close(fd);
+ session[fd]->eof = 1;
+ printf("clif_parse: session #%d, bad packet version -> disconnected.\n", fd);
+ return 0;
+ }
// check authentification packet to know packet version
- else {
+ } else {
+ // packet DB
+ if (IS_PACKET_DB_VER (cmd)) {
+ if (RFIFOREST(fd) >= packet_db[clif_config.packet_db_ver][cmd].len &&
+ (RFIFOB(fd,packet_db[clif_config.packet_db_ver][cmd].pos[4]) == 0 ||
+ RFIFOB(fd,packet_db[clif_config.packet_db_ver][cmd].pos[4]) == 1)) {// 00 = Female, 01 = Male
+ packet_ver = clif_config.packet_db_ver;
+ }
// 0x72
- if (cmd == 0x72) {
+ } else if (cmd == 0x72) {
if (RFIFOREST(fd) >= 39 && (RFIFOB(fd,38) == 0 || RFIFOB(fd,38) == 1)) // 00 = Female, 01 = Male
- packet_ver = 7; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ packet_ver = 7; // 7: 13july04
else if (RFIFOREST(fd) >= 22 && (RFIFOB(fd,21) == 0 || RFIFOB(fd,21) == 1)) // 00 = Female, 01 = Male
- packet_ver = 6; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ packet_ver = 6; // 6: 7july04
else if (RFIFOREST(fd) >= 19 && (RFIFOB(fd,18) == 0 || RFIFOB(fd,18) == 1)) // 00 = Female, 01 = Male
- packet_ver = 5; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ packet_ver = 5; // 5: old
// else probably incomplete packet
else if (RFIFOREST(fd) < 19)
return 0;
// 0x7E
} else if (cmd == 0x7E) {
if (RFIFOREST(fd) >= 37 && (RFIFOB(fd,36) == 0 || RFIFOB(fd,36) == 1)) // 00 = Female, 01 = Male
- packet_ver = 9; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ packet_ver = 9; // 9: 9aug04/16aug04/17aug04
else if (RFIFOREST(fd) >= 33 && (RFIFOB(fd,32) == 0 || RFIFOB(fd,32) == 1)) // 00 = Female, 01 = Male
- packet_ver = 8; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ packet_ver = 8; // 8: 26july04
// else probably incomplete packet
else if (RFIFOREST(fd) < 33)
return 0;
// 0xF5
- } else {
+ } else if (cmd == 0xF5) {
if (RFIFOREST(fd) >= 34 && (RFIFOB(fd,33) == 0 || RFIFOB(fd,33) == 1)) // 00 = Female, 01 = Male
- packet_ver = 10; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ packet_ver = 10; // 10: 6sept04
else if (RFIFOREST(fd) >= 33 && (RFIFOB(fd,32) == 0 || RFIFOB(fd,32) == 1)) // 00 = Female, 01 = Male
- packet_ver = 12; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ packet_ver = 12; // 12: 18oct04
else if (RFIFOREST(fd) >= 32 && (RFIFOB(fd,31) == 0 || RFIFOB(fd,31) == 1)) // 00 = Female, 01 = Male
- packet_ver = 11; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
- else if (RFIFOREST(fd) >= 29 && (RFIFOB(fd,28) == 0 || RFIFOB(fd,28) == 1)) // 00 = Female, 01 = Male
- packet_ver = 13; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
+ packet_ver = 11; // 11: 21sept04
+ else if (RFIFOREST(fd) >= 29 && (RFIFOB(fd,28) == 0 || RFIFOB(fd,28) == 1)) { // 00 = Female, 01 = Male
+ if (RFIFOL(fd,3) > 700000 && RFIFOL(fd,10) >= 150000 && RFIFOL(fd,10) < 5000000) // account id / char id (more than 5.000.000 characters?) [Yor]
+ packet_ver = 15; // 14: 6dec04
+ else
+ packet_ver = 13; // 13: 25oct04 (by [Yor])
+ }
// else probably incomplete packet
else if (RFIFOREST(fd) < 29)
return 0;
+ // 0x9B
+ } else if (cmd == 0x9B) {
+ if (RFIFOREST(fd) >= 32 && (RFIFOB(fd,31) == 0 || RFIFOB(fd,31) == 1)) // 00 = Female, 01 = Male
+ packet_ver = 16; // 16: 10jan05
+ else if (RFIFOREST(fd) < 32)
+ return 0;
+ } else {
+ // unknown client? leave packet ver as 0 so it'll disconnect anyway
}
+
// check if version is accepted
- if ((packet_ver == 5 && (battle_config.packet_ver_flag & 1) == 0) ||
- (packet_ver == 6 && (battle_config.packet_ver_flag & 2) == 0) ||
- (packet_ver == 7 && (battle_config.packet_ver_flag & 4) == 0) ||
- (packet_ver == 8 && (battle_config.packet_ver_flag & 8) == 0) ||
- (packet_ver == 9 && (battle_config.packet_ver_flag & 16) == 0) ||
- (packet_ver == 10 && (battle_config.packet_ver_flag & 32) == 0) ||
- (packet_ver == 11 && (battle_config.packet_ver_flag & 64) == 0) ||
- (packet_ver == 12 && (battle_config.packet_ver_flag & 128) == 0) ||
- (packet_ver == 13 && (battle_config.packet_ver_flag & 256) == 0)) {
+ if (packet_ver < 5 || // reject really old client versions
+ (packet_ver <= 9 && (battle_config.packet_ver_flag & 1) == 0) || // older than 6sept04
+ (packet_ver == 10 && (battle_config.packet_ver_flag & 2) == 0) ||
+ (packet_ver == 11 && (battle_config.packet_ver_flag & 4) == 0) ||
+ (packet_ver == 12 && (battle_config.packet_ver_flag & 8) == 0) ||
+ (packet_ver == 13 && (battle_config.packet_ver_flag & 16) == 0) ||
+ (packet_ver == 14 && (battle_config.packet_ver_flag & 32) == 0) ||
+ (packet_ver == 15 && (battle_config.packet_ver_flag & 64) == 0) ||
+ (packet_ver == 16 && (battle_config.packet_ver_flag & 128) == 0) ||
+ packet_ver > MAX_PACKET_VER || // no packet version support yet
+ // identified version, but unknown client?
+ (!sd && packet_db[packet_ver][cmd].func != clif_parse_WantToConnection)) {
WFIFOW(fd,0) = 0x6a;
WFIFOB(fd,2) = 5; // 05 = Game's EXE is not the latest version
WFIFOSET(fd,23);
- session[fd]->eof = 1;
+ clif_setwaitclose(fd);
return 0;
}
}
// ƒQ[ƒ€—pˆÈŠOƒpƒPƒbƒg‚©A”FØ‚ðI‚¦‚é‘O‚É0072ˆÈŠO‚ª—ˆ‚½‚çAØ’f‚·‚é
- if (packet_ver < 5 || packet_ver > 13 || // if packet is not inside these values: session is incorrect?? or auth packet is unknown
- cmd >= 0x220 || packet_size_table[packet_ver-5][cmd] == 0) {
+ if (cmd >= MAX_PACKET_DB || packet_db[packet_ver][cmd].len == 0) { // if packet is not inside these values: session is incorrect?? or auth packet is unknown
if (!fd)
return 0;
+ close(fd);
session[fd]->eof = 1;
printf("clif_parse: session #%d, packet 0x%x (%d bytes received) -> disconnected.\n", fd, cmd, RFIFOREST(fd));
return 0;
}
// ƒpƒPƒbƒg’·‚ðŒvŽZ
- packet_len = packet_size_table[packet_ver-5][cmd];
+ packet_len = packet_db[packet_ver][cmd].len;
if (packet_len == -1) {
if (RFIFOREST(fd) < 4)
return 0; // ‰Â•Ï’·ƒpƒPƒbƒg‚Å’·‚³‚ÌŠ‚܂Ńf[ƒ^‚ª—ˆ‚ĂȂ¢
packet_len = RFIFOW(fd,2);
if (packet_len < 4 || packet_len > 32768) {
- session[fd]->eof = 1;
+ close(fd);
+ session[fd]->eof =1;
return 0;
}
}
if (RFIFOREST(fd) < packet_len)
return 0; // ‚Ü‚¾1ƒpƒPƒbƒg•ªƒf[ƒ^‚ª‘µ‚Á‚ĂȂ¢
+ #if DUMP_ALL_PACKETS
+ dump = 1;
+ #endif
+
if (sd && sd->state.auth == 1 && sd->state.waitingdisconnect == 1) { // Ø’f‘Ò‚¿‚ÌꇃpƒPƒbƒg‚ðˆ—‚µ‚È‚¢
- } else if (packet_ver < 8 && clif_parse_func_table[0][cmd]) { // packet version 5-6-7 use same functions, but size are different
+ } else if (packet_db[packet_ver][cmd].func) { // packet version 5-6-7 use same functions, but size are different
// ƒpƒPƒbƒgˆ—
- clif_parse_func_table[0][cmd](fd, sd);
- } else if (packet_ver >= 8 && clif_parse_func_table[packet_ver - 7][cmd]) {
- // ƒpƒPƒbƒgˆ—
- clif_parse_func_table[packet_ver - 7][cmd](fd, sd);
+ packet_db[packet_ver][cmd].func(fd, sd);
} else {
// •s–¾‚ȃpƒPƒbƒg
if (battle_config.error_log) {
- if (fd)
- printf("\nclif_parse: session #%d, packet 0x%x, lenght %d\n", fd, cmd, packet_len);
-#ifdef DUMP_UNKNOWN_PACKET
+#if DUMP_UNKNOWN_PACKET
{
int i;
FILE *fp;
char packet_txt[256] = "save/packet.txt";
time_t now;
- printf("---- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F");
- for(i = 0; i < packet_len; i++) {
- if ((i & 15) == 0)
- printf("\n%04X ",i);
- printf("%02X ", RFIFOB(fd,i));
- }
- if (sd && sd->state.auth) {
- if (sd->status.name != NULL)
- printf("\nAccount ID %d, character ID %d, player name %s.\n",
- sd->status.account_id, sd->status.char_id, sd->status.name);
- else
- printf("\nAccount ID %d.\n", sd->bl.id);
- } else if (sd) // not authentified! (refused by char-server or disconnect before to be authentified)
- printf("\nAccount ID %d.\n", sd->bl.id);
+ dump = 1;
if ((fp = fopen(packet_txt, "a")) == NULL) {
printf("clif.c: cant write [%s] !!! data is lost !!!\n", packet_txt);
@@ -10233,218 +10845,618 @@ static int clif_parse(int fd) {
#endif
}
}
+
+ if (dump) {
+ int i;
+ if (fd)
+ printf("\nclif_parse: session #%d, packet 0x%x, lenght %d\n", fd, cmd, packet_len);
+ printf("---- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F");
+ for(i = 0; i < packet_len; i++) {
+ if ((i & 15) == 0)
+ printf("\n%04X ",i);
+ printf("%02X ", RFIFOB(fd,i));
+ }
+ if (sd && sd->state.auth) {
+ if (sd->status.name != NULL)
+ printf("\nAccount ID %d, character ID %d, player name %s.\n",
+ sd->status.account_id, sd->status.char_id, sd->status.name);
+ else
+ printf("\nAccount ID %d.\n", sd->bl.id);
+ } else if (sd) // not authentified! (refused by char-server or disconnect before to be authentified)
+ printf("\nAccount ID %d.\n", sd->bl.id);
+ }
+
RFIFOSKIP(fd, packet_len);
return 0;
}
/*==========================================
+ * ƒpƒPƒbƒgƒf[ƒ^ƒx[ƒX“ǂݞ‚Ý
+ *------------------------------------------
+ */
+static int packetdb_readdb(void)
+{
+ FILE *fp;
+ char line[1024];
+ int ln=0;
+ int cmd,j,k,packet_ver;
+ char *str[64],*p,*str2[64],*p2,w1[64],w2[64];
+
+ struct {
+ void (*func)(int, struct map_session_data *);
+ char *name;
+ } clif_parse_func[]={
+ {clif_parse_WantToConnection,"wanttoconnection"},
+ {clif_parse_LoadEndAck,"loadendack"},
+ {clif_parse_TickSend,"ticksend"},
+ {clif_parse_WalkToXY,"walktoxy"},
+ {clif_parse_QuitGame,"quitgame"},
+ {clif_parse_GetCharNameRequest,"getcharnamerequest"},
+ {clif_parse_GlobalMessage,"globalmessage"},
+ {clif_parse_MapMove,"mapmove"},
+ {clif_parse_ChangeDir,"changedir"},
+ {clif_parse_Emotion,"emotion"},
+ {clif_parse_HowManyConnections,"howmanyconnections"},
+ {clif_parse_ActionRequest,"actionrequest"},
+ {clif_parse_Restart,"restart"},
+ {clif_parse_Wis,"wis"},
+ {clif_parse_GMmessage,"gmmessage"},
+ {clif_parse_TakeItem,"takeitem"},
+ {clif_parse_DropItem,"dropitem"},
+ {clif_parse_UseItem,"useitem"},
+ {clif_parse_EquipItem,"equipitem"},
+ {clif_parse_UnequipItem,"unequipitem"},
+ {clif_parse_NpcClicked,"npcclicked"},
+ {clif_parse_NpcBuySellSelected,"npcbuysellselected"},
+ {clif_parse_NpcBuyListSend,"npcbuylistsend"},
+ {clif_parse_NpcSellListSend,"npcselllistsend"},
+ {clif_parse_CreateChatRoom,"createchatroom"},
+ {clif_parse_ChatAddMember,"chataddmember"},
+ {clif_parse_ChatRoomStatusChange,"chatroomstatuschange"},
+ {clif_parse_ChangeChatOwner,"changechatowner"},
+ {clif_parse_KickFromChat,"kickfromchat"},
+ {clif_parse_ChatLeave,"chatleave"},
+ {clif_parse_TradeRequest,"traderequest"},
+ {clif_parse_TradeAck,"tradeack"},
+ {clif_parse_TradeAddItem,"tradeadditem"},
+ {clif_parse_TradeOk,"tradeok"},
+ {clif_parse_TradeCancel,"tradecancel"},
+ {clif_parse_TradeCommit,"tradecommit"},
+ {clif_parse_StopAttack,"stopattack"},
+ {clif_parse_PutItemToCart,"putitemtocart"},
+ {clif_parse_GetItemFromCart,"getitemfromcart"},
+ {clif_parse_RemoveOption,"removeoption"},
+ {clif_parse_ChangeCart,"changecart"},
+ {clif_parse_StatusUp,"statusup"},
+ {clif_parse_SkillUp,"skillup"},
+ {clif_parse_UseSkillToId,"useskilltoid"},
+ {clif_parse_UseSkillToPos,"useskilltopos"},
+ {clif_parse_UseSkillMap,"useskillmap"},
+ {clif_parse_RequestMemo,"requestmemo"},
+ {clif_parse_ProduceMix,"producemix"},
+ {clif_parse_NpcSelectMenu,"npcselectmenu"},
+ {clif_parse_NpcNextClicked,"npcnextclicked"},
+ {clif_parse_NpcAmountInput,"npcamountinput"},
+ {clif_parse_NpcStringInput,"npcstringinput"},
+ {clif_parse_NpcCloseClicked,"npccloseclicked"},
+ {clif_parse_ItemIdentify,"itemidentify"},
+ {clif_parse_SelectArrow,"selectarrow"},
+ {clif_parse_AutoSpell,"autospell"},
+ {clif_parse_UseCard,"usecard"},
+ {clif_parse_InsertCard,"insertcard"},
+ {clif_parse_SolveCharName,"solvecharname"},
+ {clif_parse_ResetChar,"resetchar"},
+ {clif_parse_LGMmessage,"lgmmessage"},
+ {clif_parse_MoveToKafra,"movetokafra"},
+ {clif_parse_MoveFromKafra,"movefromkafra"},
+ {clif_parse_MoveToKafraFromCart,"movetokafrafromcart"},
+ {clif_parse_MoveFromKafraToCart,"movefromkafratocart"},
+ {clif_parse_CloseKafra,"closekafra"},
+ {clif_parse_CreateParty,"createparty"},
+ {clif_parse_CreateParty2,"createparty2"},
+ {clif_parse_PartyInvite,"partyinvite"},
+ {clif_parse_ReplyPartyInvite,"replypartyinvite"},
+ {clif_parse_LeaveParty,"leaveparty"},
+ {clif_parse_RemovePartyMember,"removepartymember"},
+ {clif_parse_PartyChangeOption,"partychangeoption"},
+ {clif_parse_PartyMessage,"partymessage"},
+ {clif_parse_CloseVending,"closevending"},
+ {clif_parse_VendingListReq,"vendinglistreq"},
+ {clif_parse_PurchaseReq,"purchasereq"},
+ {clif_parse_OpenVending,"openvending"},
+ {clif_parse_CreateGuild,"createguild"},
+ {clif_parse_GuildCheckMaster,"guildcheckmaster"},
+ {clif_parse_GuildRequestInfo,"guildrequestinfo"},
+ {clif_parse_GuildChangePositionInfo,"guildchangepositioninfo"},
+ {clif_parse_GuildChangeMemberPosition,"guildchangememberposition"},
+ {clif_parse_GuildRequestEmblem,"guildrequestemblem"},
+ {clif_parse_GuildChangeEmblem,"guildchangeemblem"},
+ {clif_parse_GuildChangeNotice,"guildchangenotice"},
+ {clif_parse_GuildInvite,"guildinvite"},
+ {clif_parse_GuildReplyInvite,"guildreplyinvite"},
+ {clif_parse_GuildLeave,"guildleave"},
+ {clif_parse_GuildExplusion,"guildexplusion"},
+ {clif_parse_GuildMessage,"guildmessage"},
+ {clif_parse_GuildRequestAlliance,"guildrequestalliance"},
+ {clif_parse_GuildReplyAlliance,"guildreplyalliance"},
+ {clif_parse_GuildDelAlliance,"guilddelalliance"},
+ {clif_parse_GuildOpposition,"guildopposition"},
+ {clif_parse_GuildBreak,"guildbreak"},
+ {clif_parse_PetMenu,"petmenu"},
+ {clif_parse_CatchPet,"catchpet"},
+ {clif_parse_SelectEgg,"selectegg"},
+ {clif_parse_SendEmotion,"sendemotion"},
+ {clif_parse_ChangePetName,"changepetname"},
+ {clif_parse_GMKick,"gmkick"},
+ {clif_parse_GMHide,"gmhide"},
+ {clif_parse_GMReqNoChat,"gmreqnochat"},
+ {clif_parse_GMReqNoChatCount,"gmreqnochatcount"},
+ {clif_parse_sn_doridori,"sndoridori"},
+ {clif_parse_sn_explosionspirits,"snexplosionspirits"},
+ {clif_parse_PMIgnore,"wisexin"},
+ {clif_parse_PMIgnoreList,"wisexlist"},
+ {clif_parse_PMIgnoreAll,"wisall"},
+ {clif_parse_friends_list_add,"friendslistadd"},
+ {clif_parse_friends_list_remove,"friendslistremove"},
+ {clif_parse_GMkillall,"killall"},
+ {clif_parse_Recall,"summon"},
+ {clif_parse_GM_Monster_Item,"itemmonster"},
+ {clif_parse_Shift,"shift"},
+ {clif_parse_debug,"debug"},
+
+ {NULL,NULL}
+ };
+
+ if( (fp=fopen("db/packet_db.txt","r"))==NULL ){
+ printf("can't read db/packet_db.txt\n");
+ return 1;
+ }
+
+ clif_config.packet_db_ver = MAX_PACKET_VER;
+ packet_ver = MAX_PACKET_VER; // read into packet_db's version by default
+
+ while(fgets(line,1020,fp)){
+ if(line[0]=='/' && line[1]=='/')
+ continue;
+ if (sscanf(line,"%[^:]: %[^\r\n]",w1,w2) == 2) {
+ if(strcmpi(w1,"packet_ver")==0) {
+ packet_ver = atoi(w2);
+ // copy from previous version into new version and continue
+ // - indicating all following packets should be read into the newer version
+ // -- on 2nd thought, rereading everything isn't the best thing to do...
+ // memcpy(&packet_db[packet_ver], &packet_db[packet_ver - 1], sizeof(packet_db[0]));
+ continue;
+ } else if(strcmpi(w1,"packet_db_ver")==0) {
+ // optional: if you do not wish to read multiple versions from the packet_db,
+ // remove all "packet_ver: ##" lines, and define the packet DB version with this
+ if(strcmpi(w2,"default")==0)
+ clif_config.packet_db_ver = MAX_PACKET_VER;
+ else {
+ // to manually set the packet DB version
+ clif_config.packet_db_ver = atoi(w2);
+ // check for invalid version
+ if (clif_config.packet_db_ver > MAX_PACKET_VER ||
+ clif_config.packet_db_ver < 0)
+ clif_config.packet_db_ver = MAX_PACKET_VER;
+ }
+ continue;
+ } else if(strcmpi(w1,"enable_packet_db")==0) {
+ // whether we want to allow identifying clients via the packet DB
+ clif_config.enable_packet_db = battle_config_switch(w2);
+ // if we don't want to read the packet DB, and use hardcoded values only
+ if (!clif_config.enable_packet_db)
+ return 0;
+ continue;
+ } else if(strcmpi(w1,"prefer_packet_db")==0) {
+ // whether the packet DB takes higher precedence over the hardcoded one (type 1)
+ // and whether to overwrite predefined packet length and functions when reading
+ // from the DB (type 2)
+ clif_config.prefer_packet_db = battle_config_switch(w2); // not used for now
+ continue;
+ }
+ }
+
+ memset(str,0,sizeof(str));
+ for(j=0,p=line;j<4 && p;j++){
+ str[j]=p;
+ p=strchr(p,',');
+ if(p) *p++=0;
+ }
+ if(str[0]==NULL)
+ continue;
+ cmd=strtol(str[0],(char **)NULL,0);
+ if(cmd<=0 || cmd>=MAX_PACKET_DB)
+ continue;
+ if(str[1]==NULL){
+ sprintf(tmp_output, "packet_db: packet len error\n");
+ ShowError(tmp_output);
+ continue;
+ }
+ k = atoi(str[1]);
+ // if (packet_db[packet_ver][cmd].len != k && clif_config.prefer_packet_db) // not used for now
+ packet_db[packet_ver][cmd].len = k;
+
+ if(str[2]==NULL){
+ ln++;
+ continue;
+ }
+ for(j=0;j<sizeof(clif_parse_func)/sizeof(clif_parse_func[0]);j++){
+ if(clif_parse_func[j].name != NULL &&
+ strcmp(str[2],clif_parse_func[j].name)==0){
+ // if (packet_db[packet_ver][cmd].func != clif_parse_func[j].func && !clif_config.prefer_packet_db)
+ // break; // not used for now
+ packet_db[packet_ver][cmd].func = clif_parse_func[j].func;
+ break;
+ }
+ }
+ // set the identifying cmd for the packet_db version
+ if (strcmp(str[2],"wanttoconnection")==0){
+ clif_config.connect_cmd = cmd;
+ }
+ if(str[3]==NULL){
+ sprintf(tmp_output, "packet_db: packet error\n");
+ ShowError(tmp_output);
+ exit(1);
+ }
+ for(j=0,p2=str[3];p2;j++){
+ str2[j]=p2;
+ p2=strchr(p2,':');
+ if(p2) *p2++=0;
+ k = atoi(str2[j]);
+ // if (packet_db[packet_ver][cmd].pos[j] != k && clif_config.prefer_packet_db) // not used for now
+ packet_db[packet_ver][cmd].pos[j] = k;
+ }
+
+ ln++;
+// if(packet_db[clif_config.packet_db_ver][cmd].len > 2 /* && packet_db[cmd].pos[0] == 0 */)
+// printf("packet_db ver %d: %d 0x%x %d %s %p\n",packet_ver,ln,cmd,packet_db[packet_ver][cmd].len,str[2],packet_db[packet_ver][cmd].func);
+ }
+
+ fclose(fp);
+ sprintf(tmp_output,"Done reading packet version '"CL_WHITE"%d"CL_RESET"' in '"CL_WHITE"%s"CL_RESET"'.\n", clif_config.packet_db_ver, "db/packet_db.txt");
+ ShowStatus(tmp_output);
+ return 0;
+
+}
+
+/*==========================================
*
*------------------------------------------
*/
int do_init_clif(void) {
-#ifndef __WIN32
int i;
-#endif
+ clif_config.enable_packet_db = 1; // whether to use the packet DB for client connection
+ clif_config.packet_db_ver = -1; // the main packet version of the DB
+ clif_config.prefer_packet_db = 1; // whether the packet version takes precedence
+ clif_config.connect_cmd = 0xF5; // the default packet used for connecting to the server
+
+ memset(packet_db,0,sizeof(packet_db));
+
+ // size of packet version 5 (old)
+ for(i=0;i<sizeof(packet_len_table)/sizeof(packet_len_table[0]);i++){
+ packet_db[0][i].len = packet_len_table[i];
+ }
+ // packet functions of version 5 (old)
+ for(i=0;i<sizeof(clif_parse_func_table)/sizeof(clif_parse_func_table[0]);i++){
+ packet_db[0][i].func = clif_parse_func_table[i];
+ }
+
+ // using hardcoded packet values isn't necessary with packet_db now,
+ // but... just in case, i'll leave it to initialise for now ^^;
+ // init packet version 5 and lower
+ memcpy(&packet_db[1], &packet_db[0], sizeof(packet_db[0]));
+ memcpy(&packet_db[2], &packet_db[1], sizeof(packet_db[0]));
+ memcpy(&packet_db[3], &packet_db[2], sizeof(packet_db[0]));
+ memcpy(&packet_db[4], &packet_db[3], sizeof(packet_db[0]));
+ memcpy(&packet_db[5], &packet_db[4], sizeof(packet_db[0]));
+
+#ifndef PREFER_PACKET_DB
// functions of packet version 5-6-7 are same, but size are different
+ // size of packet version 6 (7july04)
+ memcpy(&packet_db[6], &packet_db[5], sizeof(packet_db[0]));
+ packet_db[6][0x072].len = 22;
+ packet_db[6][0x085].len = 8;
+ packet_db[6][0x0a7].len = 13;
+ packet_db[6][0x113].len = 15;
+ packet_db[6][0x116].len = 15;
+ packet_db[6][0x190].len = 95;
+ // size of packet version 7 (13july04)
+ memcpy(&packet_db[7], &packet_db[6], sizeof(packet_db[0]));
+ packet_db[7][0x072].len = 39;
+ packet_db[7][0x085].len = 9;
+ packet_db[7][0x09b].len = 13;
+ packet_db[7][0x09f].len = 10;
+ packet_db[7][0x0a7].len = 17;
+ packet_db[7][0x113].len = 19;
+ packet_db[7][0x116].len = 19;
+ packet_db[7][0x190].len = 99;
// init packet function calls for packet ver 8
- memcpy(clif_parse_func_table[1], clif_parse_func_table[0], sizeof(clif_parse_func_table[0]));
- clif_parse_func_table[1][0x072] = clif_parse_DropItem;
- clif_parse_func_table[1][0x07e] = clif_parse_WantToConnection;
- clif_parse_func_table[1][0x085] = clif_parse_UseSkillToId;
- clif_parse_func_table[1][0x089] = clif_parse_GetCharNameRequest;
- clif_parse_func_table[1][0x08c] = clif_parse_UseSkillToPos;
- clif_parse_func_table[1][0x094] = clif_parse_TakeItem;
- clif_parse_func_table[1][0x09b] = clif_parse_WalkToXY;
- clif_parse_func_table[1][0x09f] = clif_parse_ChangeDir;
- clif_parse_func_table[1][0x0a2] = clif_parse_UseSkillToPos;
- clif_parse_func_table[1][0x0a7] = clif_parse_SolveCharName;
- clif_parse_func_table[1][0x0f3] = clif_parse_GlobalMessage;
- clif_parse_func_table[1][0x0f5] = clif_parse_UseItem;
- clif_parse_func_table[1][0x0f7] = clif_parse_TickSend;
- clif_parse_func_table[1][0x113] = clif_parse_MoveToKafra;
- clif_parse_func_table[1][0x116] = clif_parse_CloseKafra;
- clif_parse_func_table[1][0x190] = clif_parse_MoveFromKafra;
- clif_parse_func_table[1][0x193] = clif_parse_ActionRequest;
+ memcpy(packet_db[8], packet_db[7], sizeof(packet_db[0]));
+ packet_db[8][0x072].func = clif_parse_DropItem;
+ packet_db[8][0x07e].func = clif_parse_WantToConnection;
+ packet_db[8][0x085].func = clif_parse_UseSkillToId;
+ packet_db[8][0x089].func = clif_parse_GetCharNameRequest;
+ packet_db[8][0x08c].func = clif_parse_UseSkillToPos;
+ packet_db[8][0x094].func = clif_parse_TakeItem;
+ packet_db[8][0x09b].func = clif_parse_WalkToXY;
+ packet_db[8][0x09f].func = clif_parse_ChangeDir;
+ packet_db[8][0x0a2].func = clif_parse_UseSkillToPos;
+ packet_db[8][0x0a7].func = clif_parse_SolveCharName;
+ packet_db[8][0x0f3].func = clif_parse_GlobalMessage;
+ packet_db[8][0x0f5].func = clif_parse_UseItem;
+ packet_db[8][0x0f7].func = clif_parse_TickSend;
+ packet_db[8][0x113].func = clif_parse_MoveToKafra;
+ packet_db[8][0x116].func = clif_parse_CloseKafra;
+ packet_db[8][0x190].func = clif_parse_MoveFromKafra;
+ packet_db[8][0x193].func = clif_parse_ActionRequest;
+ // size of packet version 8 (26july04)
+ packet_db[8][0x072].len = 14;
+ packet_db[8][0x07e].len = 33;
+ packet_db[8][0x085].len = 20;
+ packet_db[8][0x089].len = 15;
+ packet_db[8][0x08c].len = 23;
+ packet_db[8][0x094].len = 10;
+ packet_db[8][0x09b].len = 6;
+ packet_db[8][0x09f].len = 13;
+ packet_db[8][0x0a2].len = 103;
+ packet_db[8][0x0a7].len = 12;
+ packet_db[8][0x0f3].len = -1;
+ packet_db[8][0x0f5].len = 17;
+ packet_db[8][0x0f7].len = 10;
+ packet_db[8][0x113].len = 16;
+ packet_db[8][0x116].len = 2;
+ packet_db[8][0x190].len = 26;
+ packet_db[8][0x193].len = 9;
// init packet function calls for packet ver 9 (same function of packet version 8, but size are different)
- memcpy(clif_parse_func_table[2], clif_parse_func_table[1], sizeof(clif_parse_func_table[0]));
+ memcpy(packet_db[9], packet_db[8], sizeof(packet_db[0]));
+ // size of packet version 9 (9aug04/16aug04/17aug04)
+ packet_db[9][0x072].len = 17;
+ packet_db[9][0x07e].len = 37;
+ packet_db[9][0x085].len = 26;
+ packet_db[9][0x089].len = 12;
+ packet_db[9][0x08c].len = 40;
+ packet_db[9][0x094].len = 13;
+ packet_db[9][0x09b].len = 15;
+ packet_db[9][0x09f].len = 12;
+ packet_db[9][0x0a2].len = 120;
+ packet_db[9][0x0a7].len = 11;
+// packet_db[9][0x0f3].len = -1;
+ packet_db[9][0x0f5].len = 24;
+ packet_db[9][0x0f7].len = 13;
+ packet_db[9][0x113].len = 23;
+// packet_db[9][0x116].len = 2;
+ packet_db[9][0x190].len = 26;
+ packet_db[9][0x193].len = 18;
+ // new packet
+ packet_db[9][0x20f].len = 10;
+ packet_db[9][0x210].len = 22;
+ packet_db[9][0x212].len = 26;
+ packet_db[9][0x213].len = 26;
+ packet_db[9][0x214].len = 42;
// init packet function calls for packet ver 10
- memcpy(clif_parse_func_table[3], clif_parse_func_table[2], sizeof(clif_parse_func_table[0]));
- clif_parse_func_table[3][0x072] = clif_parse_UseItem;
- clif_parse_func_table[3][0x07e] = clif_parse_MoveToKafra;
- clif_parse_func_table[3][0x085] = clif_parse_ActionRequest;
- clif_parse_func_table[3][0x089] = clif_parse_WalkToXY;
- clif_parse_func_table[3][0x08c] = clif_parse_UseSkillToPos;
- clif_parse_func_table[3][0x094] = clif_parse_DropItem;
- clif_parse_func_table[3][0x09b] = clif_parse_GetCharNameRequest;
- clif_parse_func_table[3][0x09f] = clif_parse_GlobalMessage;
- clif_parse_func_table[3][0x0a2] = clif_parse_SolveCharName;
- clif_parse_func_table[3][0x0a7] = clif_parse_UseSkillToPos;
- clif_parse_func_table[3][0x0f3] = clif_parse_ChangeDir;
- clif_parse_func_table[3][0x0f5] = clif_parse_WantToConnection;
- clif_parse_func_table[3][0x0f7] = clif_parse_CloseKafra;
- clif_parse_func_table[3][0x113] = clif_parse_TakeItem;
- clif_parse_func_table[3][0x116] = clif_parse_TickSend;
- clif_parse_func_table[3][0x190] = clif_parse_UseSkillToId;
- clif_parse_func_table[3][0x193] = clif_parse_MoveFromKafra;
+ memcpy(packet_db[10], packet_db[9], sizeof(packet_db[0]));
+ packet_db[10][0x072].func = clif_parse_UseItem;
+ packet_db[10][0x07e].func = clif_parse_MoveToKafra;
+ packet_db[10][0x085].func = clif_parse_ActionRequest;
+ packet_db[10][0x089].func = clif_parse_WalkToXY;
+ packet_db[10][0x08c].func = clif_parse_UseSkillToPos;
+ packet_db[10][0x094].func = clif_parse_DropItem;
+ packet_db[10][0x09b].func = clif_parse_GetCharNameRequest;
+ packet_db[10][0x09f].func = clif_parse_GlobalMessage;
+ packet_db[10][0x0a2].func = clif_parse_SolveCharName;
+ packet_db[10][0x0a7].func = clif_parse_UseSkillToPos;
+ packet_db[10][0x0f3].func = clif_parse_ChangeDir;
+ packet_db[10][0x0f5].func = clif_parse_WantToConnection;
+ packet_db[10][0x0f7].func = clif_parse_CloseKafra;
+ packet_db[10][0x113].func = clif_parse_TakeItem;
+ packet_db[10][0x116].func = clif_parse_TickSend;
+ packet_db[10][0x190].func = clif_parse_UseSkillToId;
+ packet_db[10][0x193].func = clif_parse_MoveFromKafra;
+ // size of packet version 10 (6sept04)
+ packet_db[10][0x072].len = 20;
+ packet_db[10][0x07e].len = 19;
+ packet_db[10][0x085].len = 23;
+ packet_db[10][0x089].len = 9;
+ packet_db[10][0x08c].len = 105;
+ packet_db[10][0x094].len = 17;
+ packet_db[10][0x09b].len = 14;
+ packet_db[10][0x09f].len = -1;
+ packet_db[10][0x0a2].len = 14;
+ packet_db[10][0x0a7].len = 25;
+ packet_db[10][0x0f3].len = 10;
+ packet_db[10][0x0f5].len = 34;
+ packet_db[10][0x0f7].len = 2;
+ packet_db[10][0x113].len = 11;
+ packet_db[10][0x116].len = 11;
+ packet_db[10][0x190].len = 22;
+ packet_db[10][0x193].len = 17;
// init packet function calls for packet ver 11 (same function of packet version 10, but size are different)
- memcpy(clif_parse_func_table[4], clif_parse_func_table[3], sizeof(clif_parse_func_table[0]));
+ memcpy(packet_db[11], packet_db[10], sizeof(packet_db[0]));
+ // size of packet version 11 (21sept04)
+ packet_db[11][0x072].len = 18;
+ packet_db[11][0x07e].len = 25;
+ packet_db[11][0x085].len = 9;
+ packet_db[11][0x089].len = 14;
+ packet_db[11][0x08c].len = 109;
+ packet_db[11][0x094].len = 19;
+ packet_db[11][0x09b].len = 10;
+// packet_db[11][0x09f].len = -1;
+ packet_db[11][0x0a2].len = 10;
+ packet_db[11][0x0a7].len = 29;
+ packet_db[11][0x0f3].len = 18;
+ packet_db[11][0x0f5].len = 32;
+// packet_db[11][0x0f7].len = 2;
+ packet_db[11][0x113].len = 14;
+ packet_db[11][0x116].len = 14;
+ packet_db[11][0x190].len = 14;
+ packet_db[11][0x193].len = 12;
// init packet function calls for packet ver 12 (same function of packet version 11, but size are different)
- memcpy(clif_parse_func_table[5], clif_parse_func_table[4], sizeof(clif_parse_func_table[0]));
+ memcpy(packet_db[12], packet_db[11], sizeof(packet_db[0]));
+ // size of packet version 12 (18oct04)
+ packet_db[12][0x072].len = 17;
+ packet_db[12][0x07e].len = 16;
+// packet_db[12][0x085].len = 9;
+ packet_db[12][0x089].len = 6;
+ packet_db[12][0x08c].len = 103;
+ packet_db[12][0x094].len = 14;
+ packet_db[12][0x09b].len = 15;
+// packet_db[12][0x09f].len = -1;
+ packet_db[12][0x0a2].len = 12;
+ packet_db[12][0x0a7].len = 23;
+ packet_db[12][0x0f3].len = 13;
+ packet_db[12][0x0f5].len = 33;
+// packet_db[12][0x0f7].len = 2;
+ packet_db[12][0x113].len = 10;
+ packet_db[12][0x116].len = 10;
+ packet_db[12][0x190].len = 20;
+ packet_db[12][0x193].len = 26;
// init packet function calls for packet ver 13 (same function of packet version 12, but size are different)
- memcpy(clif_parse_func_table[6], clif_parse_func_table[5], sizeof(clif_parse_func_table[0]));
-
- // size of packet version 5
- memcpy(&packet_size_table[0], &packet_len_table, sizeof(packet_len_table));
- // size of packet version 6
- memcpy(&packet_size_table[1], &packet_size_table[0], sizeof(packet_len_table));
- packet_size_table[1][0x072] = 22;
- packet_size_table[1][0x085] = 8;
- packet_size_table[1][0x0a7] = 13;
- packet_size_table[1][0x113] = 15;
- packet_size_table[1][0x116] = 15;
- packet_size_table[1][0x190] = 95;
- // size of packet version 7
- memcpy(&packet_size_table[2], &packet_size_table[1], sizeof(packet_len_table));
- packet_size_table[2][0x072] = 39;
- packet_size_table[2][0x085] = 9;
- packet_size_table[2][0x09b] = 13;
- packet_size_table[2][0x09f] = 10;
- packet_size_table[2][0x0a7] = 17;
- packet_size_table[2][0x113] = 19;
- packet_size_table[2][0x116] = 19;
- packet_size_table[2][0x190] = 99;
- // size of packet version 8
- memcpy(&packet_size_table[3], &packet_size_table[2], sizeof(packet_len_table));
- packet_size_table[3][0x072] = 14;
- packet_size_table[3][0x07e] = 33;
- packet_size_table[3][0x085] = 20;
- packet_size_table[3][0x089] = 15;
- packet_size_table[3][0x08c] = 23;
- packet_size_table[3][0x094] = 10;
- packet_size_table[3][0x09b] = 6;
- packet_size_table[3][0x09f] = 13;
- packet_size_table[3][0x0a2] = 103;
- packet_size_table[3][0x0a7] = 12;
- packet_size_table[3][0x0f3] = -1;
- packet_size_table[3][0x0f5] = 17;
- packet_size_table[3][0x0f7] = 10;
- packet_size_table[3][0x113] = 16;
- packet_size_table[3][0x116] = 2;
- packet_size_table[3][0x190] = 26;
- packet_size_table[3][0x193] = 9;
- // size of packet version 9
- memcpy(&packet_size_table[4], &packet_size_table[3], sizeof(packet_len_table));
- packet_size_table[4][0x072] = 17;
- packet_size_table[4][0x07e] = 37;
- packet_size_table[4][0x085] = 26;
- packet_size_table[4][0x089] = 12;
- packet_size_table[4][0x08c] = 40;
- packet_size_table[4][0x094] = 13;
- packet_size_table[4][0x09b] = 15;
- packet_size_table[4][0x09f] = 12;
- packet_size_table[4][0x0a2] = 120;
- packet_size_table[4][0x0a7] = 11;
-// packet_size_table[4][0x0f3] = -1;
- packet_size_table[4][0x0f5] = 24;
- packet_size_table[4][0x0f7] = 13;
- packet_size_table[4][0x113] = 23;
-// packet_size_table[4][0x116] = 2;
- packet_size_table[4][0x190] = 26;
- packet_size_table[4][0x193] = 18;
- // new packet
- packet_size_table[4][0x20f] = 10;
- packet_size_table[4][0x210] = 22;
- packet_size_table[4][0x212] = 26;
- packet_size_table[4][0x213] = 26;
- packet_size_table[4][0x214] = 42;
- // size of packet version 10
- memcpy(&packet_size_table[5], &packet_size_table[4], sizeof(packet_len_table));
- packet_size_table[5][0x072] = 20;
- packet_size_table[5][0x07e] = 19;
- packet_size_table[5][0x085] = 23;
- packet_size_table[5][0x089] = 9;
- packet_size_table[5][0x08c] = 105;
- packet_size_table[5][0x094] = 17;
- packet_size_table[5][0x09b] = 14;
- packet_size_table[5][0x09f] = -1;
- packet_size_table[5][0x0a2] = 14;
- packet_size_table[5][0x0a7] = 25;
- packet_size_table[5][0x0f3] = 10;
- packet_size_table[5][0x0f5] = 34;
- packet_size_table[5][0x0f7] = 2;
- packet_size_table[5][0x113] = 11;
- packet_size_table[5][0x116] = 11;
- packet_size_table[5][0x190] = 22;
- packet_size_table[5][0x193] = 17;
- // size of packet version 11
- memcpy(&packet_size_table[6], &packet_size_table[5], sizeof(packet_len_table));
- packet_size_table[6][0x072] = 18;
- packet_size_table[6][0x07e] = 25;
- packet_size_table[6][0x085] = 9;
- packet_size_table[6][0x089] = 14;
- packet_size_table[6][0x08c] = 109;
- packet_size_table[6][0x094] = 19;
- packet_size_table[6][0x09b] = 10;
-// packet_size_table[6][0x09f] = -1;
- packet_size_table[6][0x0a2] = 10;
- packet_size_table[6][0x0a7] = 29;
- packet_size_table[6][0x0f3] = 18;
- packet_size_table[6][0x0f5] = 32;
-// packet_size_table[6][0x0f7] = 2;
- packet_size_table[6][0x113] = 14;
- packet_size_table[6][0x116] = 14;
- packet_size_table[6][0x190] = 14;
- packet_size_table[6][0x193] = 12;
- // size of packet version 12
- memcpy(&packet_size_table[7], &packet_size_table[6], sizeof(packet_len_table));
- packet_size_table[7][0x072] = 17;
- packet_size_table[7][0x07e] = 16;
-// packet_size_table[7][0x085] = 9;
- packet_size_table[7][0x089] = 6;
- packet_size_table[7][0x08c] = 103;
- packet_size_table[7][0x094] = 14;
- packet_size_table[7][0x09b] = 15;
-// packet_size_table[7][0x09f] = -1;
- packet_size_table[7][0x0a2] = 12;
- packet_size_table[7][0x0a7] = 23;
- packet_size_table[7][0x0f3] = 13;
- packet_size_table[7][0x0f5] = 33;
-// packet_size_table[7][0x0f7] = 2;
- packet_size_table[7][0x113] = 10;
- packet_size_table[7][0x116] = 10;
- packet_size_table[7][0x190] = 20;
- packet_size_table[7][0x193] = 26;
- // size of packet version 13
- memcpy(&packet_size_table[8], &packet_size_table[7], sizeof(packet_len_table));
- packet_size_table[8][0x072] = 13;
- packet_size_table[8][0x07e] = 13;
- packet_size_table[8][0x085] = 15;
-// packet_size_table[8][0x089] = 6;
- packet_size_table[8][0x08c] = 108;
- packet_size_table[8][0x094] = 12;
- packet_size_table[8][0x09b] = 10;
-// packet_size_table[8][0x09f] = -1;
- packet_size_table[8][0x0a2] = 16;
- packet_size_table[8][0x0a7] = 28;
- packet_size_table[8][0x0f3] = 15;
- packet_size_table[8][0x0f5] = 29;
-// packet_size_table[8][0x0f7] = 2;
- packet_size_table[8][0x113] = 9;
- packet_size_table[8][0x116] = 9;
- packet_size_table[8][0x190] = 26;
- packet_size_table[8][0x193] = 22;
+ memcpy(packet_db[13], packet_db[12], sizeof(packet_db[0]));
+ // size of packet version 13 (25oct04)
+ packet_db[13][0x072].len = 13;
+ packet_db[13][0x07e].len = 13;
+ packet_db[13][0x085].len = 15;
+// packet_db[13][0x089].len = 6;
+ packet_db[13][0x08c].len = 108;
+ packet_db[13][0x094].len = 12;
+ packet_db[13][0x09b].len = 10;
+// packet_db[13][0x09f].len = -1;
+ packet_db[13][0x0a2].len = 16;
+ packet_db[13][0x0a7].len = 28;
+ packet_db[13][0x0f3].len = 15;
+ packet_db[13][0x0f5].len = 29;
+// packet_db[13][0x0f7].len = 2;
+ packet_db[13][0x113].len = 9;
+ packet_db[13][0x116].len = 9;
+ packet_db[13][0x190].len = 26;
+ packet_db[13][0x193].len = 22;
+ // init packet function calls for packet ver 14 (same function of packet version 13, but size are different)
+ memcpy(packet_db[14], packet_db[13], sizeof(packet_db[0]));
+ // size of packet version 14 - Added by nsstrunks (1nov04)
+ packet_db[14][0x072].len = 13;
+ packet_db[14][0x07e].len = 13;
+ packet_db[14][0x085].len = 15;
+ packet_db[14][0x089].len = 6;
+ packet_db[14][0x08c].len = 108;
+ packet_db[14][0x094].len = 12;
+ packet_db[14][0x09b].len = 10;
+ packet_db[14][0x09f].len = -1;
+ packet_db[14][0x0a2].len = 16;
+ packet_db[14][0x0a7].len = 28;
+ packet_db[14][0x0f3].len = 15;
+ packet_db[14][0x0f5].len = 29;
+ packet_db[14][0x113].len = 9;
+ packet_db[14][0x116].len = 9;
+ packet_db[14][0x190].len = 26;
+ packet_db[14][0x193].len = 22;
+ packet_db[14][0x215].len = 6;
+ packet_db[14][0x216].len = 6;
+ packet_db[14][0x217].len = 2;
+ packet_db[14][0x218].len = 2;
+ packet_db[14][0x219].len = 282;
+ packet_db[14][0x21a].len = 282;
+ packet_db[14][0x21b].len = 10;
+ packet_db[14][0x21c].len = 10;
+// packet_db[14][0x143].len = 23; // is this required? uncomment if it is
+ // Init packet function calls for packet ver 15
+ memcpy(packet_db[15], packet_db[14], sizeof(packet_db[0]));
+ packet_db[15][0x072].func = clif_parse_UseSkillToId;
+ packet_db[15][0x07e].func = clif_parse_UseSkillToPos;
+ packet_db[15][0x089].func = clif_parse_TickSend;
+ packet_db[15][0x085].func = clif_parse_GlobalMessage;
+ packet_db[15][0x08c].func = clif_parse_GetCharNameRequest;
+ packet_db[15][0x094].func = clif_parse_MoveToKafra;
+ packet_db[15][0x09b].func = clif_parse_CloseKafra;
+ packet_db[15][0x09f].func = clif_parse_ActionRequest;
+ packet_db[15][0x0a2].func = clif_parse_TakeItem;
+ packet_db[15][0x0a7].func = clif_parse_WalkToXY;
+ packet_db[15][0x0f3].func = clif_parse_ChangeDir;
+ packet_db[15][0x0f5].func = clif_parse_WantToConnection;
+ packet_db[15][0x0f7].func = clif_parse_SolveCharName;
+ packet_db[15][0x113].func = clif_parse_UseSkillToPos;
+ packet_db[15][0x116].func = clif_parse_DropItem;
+ packet_db[15][0x190].func = clif_parse_UseItem;
+ packet_db[15][0x193].func = clif_parse_MoveFromKafra;
+ // Size of packet version 15 - Added by nsstrunks (6dec04)
+ packet_db[15][0x072].len = 22;
+ packet_db[15][0x07e].len = 30;
+ packet_db[15][0x094].len = 14;
+ packet_db[15][0x09f].len = 18;
+ packet_db[15][0x085].len = -1;
+ packet_db[15][0x08c].len = 13;
+ packet_db[15][0x089].len = 7;
+ packet_db[15][0x09b].len = 2;
+ packet_db[15][0x0a2].len = 7;
+ packet_db[15][0x0a7].len = 7;
+ packet_db[15][0x0f3].len = 8;
+ packet_db[15][0x0f5].len = 29;
+ packet_db[15][0x0f7].len = 14;
+ packet_db[15][0x113].len = 110;
+ packet_db[15][0x116].len = 12;
+ packet_db[15][0x190].len = 15;
+ packet_db[15][0x193].len = 21;
+ packet_db[15][0x21d].len = 6;
+ packet_db[15][0x222].len = 6;
+ packet_db[15][0x221].len = -1;
+ packet_db[15][0x223].len = 8;
+ // Init packet function calls for packet ver 16
+ memcpy(packet_db[16], packet_db[15], sizeof(packet_db[0]));
+ packet_db[16][0x072].func = clif_parse_UseSkillToId;
+ packet_db[16][0x07e].func = clif_parse_UseSkillToPos;
+ packet_db[16][0x089].func = clif_parse_TickSend;
+ packet_db[16][0x0f3].func = clif_parse_GlobalMessage;
+ packet_db[16][0x08c].func = clif_parse_GetCharNameRequest;
+ packet_db[16][0x094].func = clif_parse_MoveToKafra;
+ packet_db[16][0x193].func = clif_parse_CloseKafra;
+ packet_db[16][0x190].func = clif_parse_ActionRequest;
+ packet_db[16][0x0f5].func = clif_parse_TakeItem;
+ packet_db[16][0x0a7].func = clif_parse_WalkToXY;
+ packet_db[16][0x085].func = clif_parse_ChangeDir;
+ packet_db[16][0x09b].func = clif_parse_WantToConnection;
+ packet_db[16][0x0a2].func = clif_parse_SolveCharName;
+ packet_db[16][0x113].func = clif_parse_UseSkillToPos;
+ packet_db[16][0x116].func = clif_parse_DropItem;
+ packet_db[16][0x09f].func = clif_parse_UseItem;
+ packet_db[16][0x0f7].func = clif_parse_MoveFromKafra;
+ // Size of packet version 16 [10jan05]
+ packet_db[16][0x072].len = 26;
+ packet_db[16][0x07e].len = 114;
+ packet_db[16][0x089].len = 9;
+ packet_db[16][0x0f3].len = -1;
+ packet_db[16][0x08c].len = 8;
+ packet_db[16][0x094].len = 20;
+ packet_db[16][0x193].len = 2;
+ packet_db[16][0x190].len = 20;
+ packet_db[16][0x0f5].len = 9;
+ packet_db[16][0x0a7].len = 13;
+ packet_db[16][0x085].len = 23;
+ packet_db[16][0x09b].len = 32;
+ packet_db[16][0x0a2].len = 11;
+ packet_db[16][0x113].len = 34;
+ packet_db[16][0x116].len = 20;
+ packet_db[16][0x09f].len = 17;
+ packet_db[16][0x0f7].len = 21;
+ packet_db[16][0x143].len = 10;
+ // Init packet function calls for the packet_db.txt (17)
+ memcpy(packet_db[MAX_PACKET_VER], packet_db[MAX_PACKET_VER - 1], sizeof(packet_db[0]));
+#endif
+
+ if (clif_config.enable_packet_db)
+ packetdb_readdb();
set_defaultparse(clif_parse);
#ifdef __WIN32
- if (!make_listen_port(map_port)) {
+ //if (!make_listen_port(map_port)) {
+ if (!make_listen_bind(bind_ip,map_port)) {
printf("cant bind game port\n");
exit(1);
}
#else
for(i = 0; i < 10; i++) {
- if (make_listen_port(map_port))
+ //if (make_listen_port(map_port))
+ if (make_listen_bind(bind_ip,map_port))
break;
sleep(20);
}
diff --git a/src/map/clif.h b/src/map/clif.h
index cf03820b1..b23eed5a6 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -13,7 +13,25 @@ typedef unsigned int in_addr_t;
#include "map.h"
+#define MAX_PACKET_DB 0x224
+#define MAX_PACKET_VER 17
+
+struct packet_db {
+ short len;
+ void (*func)(int, struct map_session_data *);
+ short pos[20];
+};
+extern struct packet_db packet_db[MAX_PACKET_VER + 1][MAX_PACKET_DB];
+
+extern struct Clif_Config {
+ int enable_packet_db;
+ int packet_db_ver;
+ int prefer_packet_db;
+ int connect_cmd;
+} clif_config;
+
void clif_setip(char*);
+void clif_setbindip(char*);
void clif_setport(int);
in_addr_t clif_getip(void);
@@ -74,7 +92,7 @@ int clif_misceffect(struct block_list*,int); // area
int clif_misceffect2(struct block_list *bl,int type);
int clif_changeoption(struct block_list*); // area
int clif_useitemack(struct map_session_data*,int,int,int); // self
-
+void clif_GlobalMessage(struct block_list *bl,char *message);
int clif_createchat(struct map_session_data*,int); // self
int clif_dispchat(struct chat_data*,int); // area or fd
int clif_joinchatfail(struct map_session_data*,int); // self
@@ -84,14 +102,17 @@ int clif_changechatowner(struct chat_data*,struct map_session_data*); // chat
int clif_clearchat(struct chat_data*,int); // area or fd
int clif_leavechat(struct chat_data*,struct map_session_data*); // chat
int clif_changechatstatus(struct chat_data*); // chat
+int clif_refresh(struct map_session_data*); // self
void clif_emotion(struct block_list *bl,int type);
void clif_talkiebox(struct block_list *bl,char* talkie);
void clif_wedding_effect(struct block_list *bl);
//void clif_sitting(int fd, struct map_session_data *sd);
//void clif_callpartner(struct map_session_data *sd);
+void clif_adopt_process(struct map_session_data *sd);
void clif_sitting(struct map_session_data *sd);
void clif_soundeffect(struct map_session_data *sd,struct block_list *bl,char *name,int type);
+int clif_soundeffectall(struct block_list *bl, char *name, int type);
// trade
int clif_traderequest(struct map_session_data *sd,char *name);
@@ -124,8 +145,8 @@ int clif_petinsight(struct block_list *bl,va_list ap);
int clif_npcoutsight(struct block_list *bl,va_list ap);
int clif_npcinsight(struct block_list *bl,va_list ap);
-int clif_class_change(struct block_list *bl,int class,int type);
-int clif_mob_class_change(struct mob_data *md,int class);
+int clif_class_change(struct block_list *bl,int class_,int type);
+int clif_mob_class_change(struct mob_data *md,int class_);
int clif_mob_equip(struct mob_data *md,int nameid); // [Valaris]
int clif_skillinfo(struct map_session_data *sd,int skillid,int type,int range);
@@ -164,7 +185,7 @@ int clif_autospell(struct map_session_data *sd,int skilllv);
int clif_devotion(struct map_session_data *sd,int target);
int clif_spiritball(struct map_session_data *sd);
int clif_combo_delay(struct block_list *src,int wait);
-int clif_bladestop(struct block_list *src,struct block_list *dst,int bool);
+int clif_bladestop(struct block_list *src,struct block_list *dst,int bool_);
int clif_changemapcell(int m,int x,int y,int cell_type,int type);
int clif_status_change(struct block_list *bl,int type,int flag);
@@ -173,6 +194,7 @@ int clif_wis_message(int fd,char *nick,char *mes,int mes_len);
int clif_wis_end(int fd,int flag);
int clif_solved_charname(struct map_session_data *sd,int char_id);
+int clif_update_mobhp(struct mob_data *md);
int clif_use_card(struct map_session_data *sd,int idx);
int clif_insert_card(struct map_session_data *sd,int idx_equip,int idx_card,int flag);
@@ -195,6 +217,7 @@ int clif_item_skill(struct map_session_data *sd,int skillid,int skilllv,const ch
int clif_mvp_effect(struct map_session_data *sd);
int clif_mvp_item(struct map_session_data *sd,int nameid);
int clif_mvp_exp(struct map_session_data *sd,int exp);
+void clif_changed_dir(struct block_list *bl);
// vending
int clif_openvendingreq(struct map_session_data *sd,int num);
@@ -218,6 +241,7 @@ int clif_party_message(struct party *p,int account_id,char *mes,int len);
int clif_party_move(struct party *p,struct map_session_data *sd,int online);
int clif_party_xy(struct party *p,struct map_session_data *sd);
int clif_party_hp(struct party *p,struct map_session_data *sd);
+int clif_hpmeter(struct map_session_data *sd);
// guild
int clif_guild_created(struct map_session_data *sd,int flag);
@@ -277,6 +301,7 @@ int clif_message(struct block_list *bl, char* msg); // messages (from mobs/npcs)
int clif_GM_kickack(struct map_session_data *sd,int id);
int clif_GM_kick(struct map_session_data *sd,struct map_session_data *tsd,int type);
+int clif_timedout(struct map_session_data *sd);
int clif_foreachclient(int (*)(struct map_session_data*,va_list),...);
diff --git a/src/map/guild.c b/src/map/guild.c
index a48bb3020..935377e19 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -13,11 +13,13 @@
#include "battle.h"
#include "npc.h"
#include "pc.h"
+#include "status.h"
#include "map.h"
#include "mob.h"
#include "intif.h"
#include "clif.h"
#include "skill.h"
+#include "showmsg.h"
#ifdef MEMWATCH
#include "memwatch.h"
@@ -43,6 +45,14 @@ struct guild_expcache {
int guild_id, account_id, char_id, exp;
};
+// timer for auto saving guild data during WoE
+#define GUILD_SAVE_INTERVAL 300000
+int guild_save_timer = -1;
+
+int guild_payexp_timer(int tid,unsigned int tick,int id,int data);
+int guild_gvg_eliminate_timer(int tid,unsigned int tick,int id,int data);
+int guild_save_sub(int tid,unsigned int tick,int id,int data);
+
// ƒMƒ‹ƒhƒXƒLƒ‹db‚̃AƒNƒZƒTi¡‚Í’¼‘Å‚¿‚Å‘ã—pj
int guild_skill_get_inf(int id) { // Modified for new skills [Sara]
if (id==GD_BATTLEORDER) return 4;
@@ -54,9 +64,21 @@ int guild_skill_get_inf(int id) { // Modified for new skills [Sara]
int guild_skill_get_sp(int id,int lv){ return 0; }
int guild_skill_get_range(int id){ return 0; }
int guild_skill_get_max(int id) { // Modified for new skills [Sara]
- if(id==GD_EXTENSION) return 10;
- else if(id==GD_REGENERATION) return 3;
- else return 1;
+ switch (id) {
+ case GD_GUARDUP:
+ return 3;
+ case GD_EXTENSION:
+ return 10;
+ case GD_LEADERSHIP:
+ case GD_GLORYWOUNDS:
+ case GD_SOULCOLD:
+ case GD_HAWKEYES:
+ return 5;
+ case GD_REGENERATION:
+ return 3;
+ default:
+ return 1;
+ }
}
// ƒMƒ‹ƒhƒXƒLƒ‹‚ª‚ ‚é‚©Šm”F
@@ -68,11 +90,6 @@ int guild_checkskill(struct guild *g,int id)
return g->skill[idx].lv;
}
-
-int guild_payexp_timer(int tid,unsigned int tick,int id,int data);
-int guild_gvg_eliminate_timer(int tid,unsigned int tick,int id,int data);
-
-
static int guild_read_castledb(void)
{
FILE *fp;
@@ -115,7 +132,8 @@ static int guild_read_castledb(void)
ln++;
}
fclose(fp);
- printf("read db/castle_db.txt done (count=%d)\n",ln);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"db/castle_db.txt");
+ ShowStatus(tmp_output);
return 0;
}
@@ -132,6 +150,7 @@ void do_init_guild(void)
add_timer_func_list(guild_gvg_eliminate_timer,"guild_gvg_eliminate_timer");
add_timer_func_list(guild_payexp_timer,"guild_payexp_timer");
+ add_timer_func_list(guild_save_sub, "guild_save_sub");
add_timer_interval(gettick()+GUILD_PAYEXP_INVERVAL,guild_payexp_timer,0,0,GUILD_PAYEXP_INVERVAL);
}
@@ -139,7 +158,7 @@ void do_init_guild(void)
// ŒŸõ
struct guild *guild_search(int guild_id)
{
- return numdb_search(guild_db,guild_id);
+ return (struct guild *) numdb_search(guild_db,guild_id);
}
int guild_searchname_sub(void *key,void *data,va_list ap)
{
@@ -160,7 +179,7 @@ struct guild* guild_searchname(char *str)
}
struct guild_castle *guild_castle_search(int gcid)
{
- return numdb_search(castle_db,gcid);
+ return (struct guild_castle *) numdb_search(castle_db,gcid);
}
// mapname‚ɑΉž‚µ‚½ƒAƒWƒg‚Ìgc‚ð•Ô‚·
@@ -228,7 +247,7 @@ void guild_makemember(struct guild_member *m,struct map_session_data *sd)
m->hair =sd->status.hair;
m->hair_color =sd->status.hair_color;
m->gender =sd->sex;
- m->class =sd->status.class;
+ m->class_ =sd->status.class_;
m->lv =sd->status.base_level;
m->exp =0;
m->exp_payper =0;
@@ -270,7 +289,7 @@ int guild_payexp_timer_sub(void *key,void *data,va_list ap)
c->exp=0;
dellist[(*delp)++]=dataid;
- free(c);
+ aFree(c);
return 0;
}
int guild_payexp_timer(int tid,unsigned int tick,int id,int data)
@@ -317,7 +336,7 @@ int guild_created(int account_id,int guild_id)
struct guild *g;
sd->status.guild_id=guild_id;
sd->guild_sended=0;
- if((g=numdb_search(guild_db,guild_id))!=NULL){
+ if((g=(struct guild *) numdb_search(guild_db,guild_id))!=NULL){
printf("guild: id already exists!\n");
exit(1);
}
@@ -352,7 +371,7 @@ int guild_npc_request_info(int guild_id,const char *event)
return guild_request_info(guild_id);
ev=(struct eventlist *)aCalloc(1,sizeof(struct eventlist));
- memcpy(ev->name,event,sizeof(ev->name));
+ memcpy(ev->name,event,strlen(event));
ev->next=(struct eventlist *)numdb_search(guild_infoevent_db,guild_id);
numdb_insert(guild_infoevent_db,guild_id,ev);
return guild_request_info(guild_id);
@@ -367,7 +386,7 @@ int guild_check_member(const struct guild *g)
nullpo_retr(0, g);
for(i=0;i<fd_max;i++){
- if(session[i] && (sd=session[i]->session_data) && sd->state.auth){
+ if(session[i] && (sd=(struct map_session_data *) session[i]->session_data) && sd->state.auth && !sd->state.waitingdisconnect){
if(sd->status.guild_id==g->guild_id){
int j,f=1;
for(j=0;j<MAX_GUILD;j++){ // ƒf[ƒ^‚ª‚ ‚é‚©
@@ -393,7 +412,7 @@ int guild_recv_noinfo(int guild_id)
int i;
struct map_session_data *sd;
for(i=0;i<fd_max;i++){
- if(session[i] && (sd=session[i]->session_data) && sd->state.auth){
+ if(session[i] && (sd=(struct map_session_data *) session[i]->session_data) && sd->state.auth && !sd->state.waitingdisconnect){
if(sd->status.guild_id==guild_id)
sd->status.guild_id=0;
}
@@ -409,7 +428,7 @@ int guild_recv_info(struct guild *sg)
nullpo_retr(0, sg);
- if((g=numdb_search(guild_db,sg->guild_id))==NULL){
+ if((g=(struct guild *) numdb_search(guild_db,sg->guild_id))==NULL){
g=(struct guild *)aCalloc(1,sizeof(struct guild));
numdb_insert(guild_db,sg->guild_id,g);
before=*sg;
@@ -423,9 +442,11 @@ int guild_recv_info(struct guild *sg)
for(i=bm=m=0;i<g->max_member;i++){ // sd‚ÌÝ’è‚Æl”‚ÌŠm”F
if(g->member[i].account_id>0){
struct map_session_data *sd = map_id2sd(g->member[i].account_id);
- g->member[i].sd=(sd!=NULL &&
- sd->status.char_id==g->member[i].char_id &&
- sd->status.guild_id==g->guild_id)? sd:NULL;
+ if (sd && sd->status.char_id == g->member[i].char_id &&
+ sd->status.guild_id == g->guild_id &&
+ !sd->state.waitingdisconnect)
+ g->member[i].sd = sd;
+ else sd = NULL;
m++;
}else
g->member[i].sd=NULL;
@@ -460,10 +481,13 @@ int guild_recv_info(struct guild *sg)
}
// ƒCƒxƒ“ƒg‚Ì”­¶
- if( (ev=numdb_search(guild_infoevent_db,sg->guild_id))!=NULL ){
+ if( (ev=(struct eventlist *)numdb_search(guild_infoevent_db,sg->guild_id))!=NULL ){
numdb_erase(guild_infoevent_db,sg->guild_id);
- for(;ev;ev2=ev->next,free(ev),ev=ev2){
+ while(ev){
npc_event_do(ev->name);
+ ev2=ev->next;
+ aFree(ev);
+ ev=ev2;
}
}
@@ -566,17 +590,18 @@ int guild_member_added(int guild_id,int account_id,int char_id,int flag)
if( (g=guild_search(guild_id))==NULL )
return 0;
- if((sd==NULL || sd->guild_invite==0) && flag==0){
+ if(sd==NULL || sd->guild_invite==0){
// ƒLƒƒƒ‰‘¤‚É“o˜^‚Å‚«‚È‚©‚Á‚½‚½‚ß’E‘Þ—v‹‚ðo‚·
- if(battle_config.error_log)
- printf("guild: member added error %d is not online\n",account_id);
- intif_guild_leave(guild_id,account_id,char_id,0,"**“o˜^ޏ”s**");
+ if (flag == 0) {
+ if(battle_config.error_log)
+ printf("guild: member added error %d is not online\n",account_id);
+ intif_guild_leave(guild_id,account_id,char_id,0,"**“o˜^ޏ”s**");
+ }
return 0;
}
- sd->guild_invite=0;
- sd->guild_invite_account=0;
-
- sd2=map_id2sd(sd->guild_invite_account);
+ sd2 = map_id2sd(sd->guild_invite_account);
+ sd->guild_invite = 0;
+ sd->guild_invite_account = 0;
if(flag==1){ // ޏ”s
if( sd2!=NULL )
@@ -659,11 +684,10 @@ int guild_member_leaved(int guild_id,int account_id,int char_id,int flag,
{
struct map_session_data *sd=map_id2sd(account_id);
struct guild *g=guild_search(guild_id);
- int i;
if(g!=NULL){
int i;
- for(i=0;i<g->max_member;i++)
+ for(i=0;i<g->max_member;i++) {
if( g->member[i].account_id==account_id &&
g->member[i].char_id==char_id ){
struct map_session_data *sd2=sd;
@@ -679,19 +703,21 @@ int guild_member_leaved(int guild_id,int account_id,int char_id,int flag,
g->member[i].account_id=0;
g->member[i].sd=NULL;
}
+ // ƒƒ“ƒo[ƒŠƒXƒg‚ð‘Sˆõ‚ÉÄ’Ê’m
+ for(i=0;i<g->max_member;i++){
+ if( g->member[i].sd!=NULL )
+ clif_guild_memberlist(g->member[i].sd);
+ }
+ }
}
- if(sd!=NULL && sd->status.guild_id==guild_id){
- sd->status.guild_id=0;
- sd->guild_emblem_id=0;
- sd->guild_sended=0;
- }
-
- // ƒƒ“ƒo[ƒŠƒXƒg‚ð‘Sˆõ‚ÉÄ’Ê’m
- for(i=0;i<g->max_member;i++){
- if( g->member[i].sd!=NULL )
- clif_guild_memberlist(g->member[i].sd);
+ if(sd!=NULL) {
+ if (sd->status.guild_id==guild_id){
+ sd->status.guild_id=0;
+ sd->guild_emblem_id=0;
+ sd->guild_sended=0;
+ }
}
-
+
return 0;
}
// ƒMƒ‹ƒhƒƒ“ƒo‚̃Iƒ“ƒ‰ƒCƒ“ó‘Ô/LvXV‘—M
@@ -708,7 +734,7 @@ int guild_send_memberinfoshort(struct map_session_data *sd,int online)
return 0;
intif_guild_memberinfoshort(g->guild_id,
- sd->status.account_id,sd->status.char_id,online,sd->status.base_level,sd->status.class);
+ sd->status.account_id,sd->status.char_id,online,sd->status.base_level,sd->status.class_);
if( !online ){ // ƒƒOƒAƒEƒg‚·‚é‚È‚çsd‚ðƒNƒŠƒA‚µ‚ÄI—¹
int i=guild_getindex(g,sd->status.account_id,sd->status.char_id);
@@ -736,7 +762,7 @@ int guild_send_memberinfoshort(struct map_session_data *sd,int online)
return 0;
}
// ƒMƒ‹ƒhƒƒ“ƒo‚̃Iƒ“ƒ‰ƒCƒ“ó‘Ô/LvXV’Ê’m
-int guild_recv_memberinfoshort(int guild_id,int account_id,int char_id,int online,int lv,int class)
+int guild_recv_memberinfoshort(int guild_id,int account_id,int char_id,int online,int lv,int class_)
{
int i,alv,c,idx=0,om=0,oldonline=-1;
struct guild *g=guild_search(guild_id);
@@ -748,7 +774,7 @@ int guild_recv_memberinfoshort(int guild_id,int account_id,int char_id,int onlin
oldonline=m->online;
m->online=online;
m->lv=lv;
- m->class=class;
+ m->class_=class_;
idx=i;
}
if(m->account_id>0){
@@ -771,9 +797,11 @@ int guild_recv_memberinfoshort(int guild_id,int account_id,int char_id,int onlin
for(i=0;i<g->max_member;i++){ // sdÄÝ’è
struct map_session_data *sd= map_id2sd(g->member[i].account_id);
- g->member[i].sd=(sd!=NULL &&
- sd->status.char_id==g->member[i].char_id &&
- sd->status.guild_id==guild_id)?sd:NULL;
+ if (sd && sd->status.char_id == g->member[i].char_id &&
+ sd->status.guild_id == g->guild_id &&
+ !sd->state.waitingdisconnect)
+ g->member[i].sd = sd;
+ else sd = NULL;
}
// ‚±‚±‚ɃNƒ‰ƒCƒAƒ“ƒg‚É‘—Mˆ—‚ª•K—v
@@ -788,6 +816,8 @@ int guild_send_message(struct map_session_data *sd,char *mes,int len)
if(sd->status.guild_id==0)
return 0;
intif_guild_message(sd->status.guild_id,sd->status.account_id,mes,len);
+ guild_recv_message(sd->status.guild_id,sd->status.account_id,mes,len);
+
return 0;
}
// ƒMƒ‹ƒh‰ï˜bŽóM
@@ -870,14 +900,16 @@ int guild_notice_changed(int guild_id,const char *mes1,const char *mes2)
// ƒMƒ‹ƒhƒGƒ“ƒuƒŒƒ€•ÏX
int guild_change_emblem(struct map_session_data *sd,int len,const char *data)
{
+ struct guild *g;
nullpo_retr(0, sd);
- struct guild *g = NULL;
- if ((g = guild_search(sd->status.guild_id)) && guild_checkskill(g, GD_GLORYGUILD)>0)
- return intif_guild_emblem(sd->status.guild_id,len,data);
+ if (battle_config.require_glory_guild &&
+ !((g = guild_search(sd->status.guild_id)) && guild_checkskill(g, GD_GLORYGUILD)>0)) {
+ clif_skill_fail(sd,GD_GLORYGUILD,0,0);
+ return 0;
+ }
- clif_skill_fail(sd,GD_GLORYGUILD,0,0);
- return 0;
+ return intif_guild_emblem(sd->status.guild_id,len,data);
}
// ƒMƒ‹ƒhƒGƒ“ƒuƒŒƒ€•ÏX’Ê’m
int guild_emblem_changed(int len,int guild_id,int emblem_id,const char *data)
@@ -920,8 +952,8 @@ int guild_payexp(struct map_session_data *sd,int exp)
if( (exp2=exp*per/100)<=0 )
return 0;
- if( (c=numdb_search(guild_expcache_db,sd->status.char_id))==NULL ){
- c=(struct guild_expcache *)aCalloc(1,sizeof(struct guild_expcache));
+ if( (c=(struct guild_expcache *) numdb_search(guild_expcache_db,sd->status.char_id))==NULL ){
+ c=(struct guild_expcache *)aCallocA(1,sizeof(struct guild_expcache));
c->guild_id=sd->status.guild_id;
c->account_id=sd->status.account_id;
c->char_id=sd->status.char_id;
@@ -933,6 +965,30 @@ int guild_payexp(struct map_session_data *sd,int exp)
return exp2;
}
+// Celest
+int guild_getexp(struct map_session_data *sd,int exp)
+{
+ struct guild *g;
+ struct guild_expcache *c;
+
+ nullpo_retr(0, sd);
+
+ if(sd->status.guild_id==0 || (g=guild_search(sd->status.guild_id))==NULL )
+ return 0;
+
+ if( (c=(struct guild_expcache *) numdb_search(guild_expcache_db,sd->status.char_id))==NULL ){
+ c=(struct guild_expcache *)aCallocA(1,sizeof(struct guild_expcache));
+ c->guild_id=sd->status.guild_id;
+ c->account_id=sd->status.account_id;
+ c->char_id=sd->status.char_id;
+ c->exp=exp;
+ numdb_insert(guild_expcache_db,c->char_id,c);
+ }else{
+ c->exp+=exp;
+ }
+ return exp;
+}
+
// ƒXƒLƒ‹ƒ|ƒCƒ“ƒgŠ„‚èU‚è
int guild_skillup(struct map_session_data *sd,int skill_num,int flag)
{
@@ -954,7 +1010,7 @@ int guild_skillup(struct map_session_data *sd,int skill_num,int flag)
g->skill[idx].lv < guild_skill_get_max(skill_num) ){
intif_guild_skillup(g->guild_id,skill_num,sd->status.account_id,flag);
}
- pc_calcstatus (sd, 0); // Celest
+ status_calc_pc (sd, 0); // Celest
return 0;
}
@@ -989,6 +1045,23 @@ int guild_get_alliance_count(struct guild *g,int flag)
}
return c;
}
+// “¯–¿ŠÖŒW‚©‚Ç‚¤‚©ƒ`ƒFƒbƒN
+// “¯–¿‚È‚ç1A‚»‚êˆÈŠO‚Í0
+int guild_check_alliance(int guild_id1, int guild_id2, int flag)
+{
+ struct guild *g;
+ int i;
+
+ g = guild_search(guild_id1);
+ if (g == NULL)
+ return 0;
+
+ for (i=0; i<MAX_GUILDALLIANCE; i++)
+ if ((g->alliance[i].guild_id == guild_id2) && (g->alliance[i].opposition == flag))
+ return 1;
+
+ return 0;
+}
// ƒMƒ‹ƒh“¯–¿—v‹
int guild_reqalliance(struct map_session_data *sd,int account_id)
{
@@ -1146,11 +1219,18 @@ int guild_allianceack(int guild_id1,int guild_id2,int account_id1,int account_id
int flag,const char *name1,const char *name2)
{
struct guild *g[2];
- int guild_id[2]={guild_id1,guild_id2};
- const char *guild_name[2]={name1,name2};
- struct map_session_data *sd[2]={map_id2sd(account_id1),map_id2sd(account_id2)};
+ int guild_id[2];
+ const char *guild_name[2];
+ struct map_session_data *sd[2];
int j,i;
+ guild_id[0] = guild_id1;
+ guild_id[1] = guild_id2;
+ guild_name[0] = name1;
+ guild_name[1] = name2;
+ sd[0] = map_id2sd(account_id1);
+ sd[1] = map_id2sd(account_id2);
+
g[0]=guild_search(guild_id1);
g[1]=guild_search(guild_id2);
@@ -1252,7 +1332,7 @@ int guild_broken(int guild_id,int flag)
numdb_foreach(guild_db,guild_broken_sub,guild_id);
numdb_erase(guild_db,guild_id);
guild_storage_delete(guild_id);
- free(g);
+ aFree(g);
return 0;
}
@@ -1301,7 +1381,7 @@ int guild_addcastleinfoevent(int castle_id,int index,const char *name)
ev=(struct eventlist *)aCalloc(1,sizeof(struct eventlist));
memcpy(ev->name,name,sizeof(ev->name));
- ev->next=numdb_search(guild_castleinfoevent_db,code);
+ ev->next=(struct eventlist *) numdb_search(guild_castleinfoevent_db,code);
numdb_insert(guild_castleinfoevent_db,code,ev);
return 0;
}
@@ -1346,10 +1426,13 @@ int guild_castledataloadack(int castle_id,int index,int value)
printf("guild_castledataloadack ERROR!! (Not found index=%d)\n", index);
return 0;
}
- if( (ev=numdb_search(guild_castleinfoevent_db,code))!=NULL ){
+ if( (ev=(struct eventlist *) numdb_search(guild_castleinfoevent_db,code))!=NULL ){
numdb_erase(guild_castleinfoevent_db,code);
- for(;ev;ev2=ev->next,free(ev),ev=ev2){
+ while(ev){
npc_event_do(ev->name);
+ ev2=ev->next;
+ aFree(ev);
+ ev=ev2;
}
}
return 1;
@@ -1439,6 +1522,8 @@ int guild_agit_start(void)
{ // Run All NPC_Event[OnAgitStart]
int c = npc_event_doall("OnAgitStart");
printf("NPC_Event:[OnAgitStart] Run (%d) Events by @AgitStart.\n",c);
+ // Start auto saving
+ guild_save_timer = add_timer_interval (gettick() + GUILD_SAVE_INTERVAL, guild_save_sub, 0, 0, GUILD_SAVE_INTERVAL);
return 0;
}
@@ -1446,20 +1531,82 @@ int guild_agit_end(void)
{ // Run All NPC_Event[OnAgitEnd]
int c = npc_event_doall("OnAgitEnd");
printf("NPC_Event:[OnAgitEnd] Run (%d) Events by @AgitEnd.\n",c);
+ // Stop auto saving
+ delete_timer (guild_save_timer, guild_save_sub);
return 0;
}
int guild_gvg_eliminate_timer(int tid,unsigned int tick,int id,int data)
{ // Run One NPC_Event[OnAgitEliminate]
- size_t len = strlen((const char*)data);
- char *evname=(char*)aCalloc(len + 4,sizeof(char));
+ char *name = (char*)data;
+ size_t len = (name) ? strlen(name) : 0;
+ // the rest is dangerous, but let it crash,
+ // if this happens, it's ruined anyway
+ char *evname=(char*)aMalloc( (len + 4) * sizeof(char));
int c=0;
- if(!agit_flag) return 0; // Agit already End
- memcpy(evname,(const char *)data,len - 5);
- strcpy(evname + len - 5,"Eliminate");
- c = npc_event_do(evname);
- printf("NPC_Event:[%s] Run (%d) Events.\n",evname,c);
+ if(agit_flag) // Agit not already End
+ {
+ memcpy(evname,name,len - 5);
+ strcpy(evname + len - 5,"Eliminate");
+ c = npc_event_do(evname);
+ printf("NPC_Event:[%s] Run (%d) Events.\n",evname,c);
+ }
+ if(name) aFree(name);
+ return 0;
+}
+
+static int Ghp[MAX_GUILDCASTLE][8]; // so save only if HP are changed // experimental code [Yor]
+static int Gid[MAX_GUILDCASTLE];
+int guild_save_sub(int tid,unsigned int tick,int id,int data)
+{
+ struct guild_castle *gc;
+ int i;
+
+ for(i = 0; i < MAX_GUILDCASTLE; i++) { // [Yor]
+ gc = guild_castle_search(i);
+ if (!gc) continue;
+ if (gc->guild_id != Gid[i]) {
+ // Re-save guild id if its owner guild has changed
+ // This should already be done in gldfunc_ev_agit.txt,
+ // but since people have complained... Well x3
+ guild_castledatasave(gc->castle_id, 1, gc->guild_id);
+ Gid[i] = gc->guild_id;
+ }
+ if (gc->visibleG0 == 1 && Ghp[i][0] != gc->Ghp0) {
+ guild_castledatasave(gc->castle_id, 18, gc->Ghp0);
+ Ghp[i][0] = gc->Ghp0;
+ }
+ if (gc->visibleG1 == 1 && Ghp[i][1] != gc->Ghp1) {
+ guild_castledatasave(gc->castle_id, 19, gc->Ghp1);
+ Ghp[i][1] = gc->Ghp1;
+ }
+ if (gc->visibleG2 == 1 && Ghp[i][2] != gc->Ghp2) {
+ guild_castledatasave(gc->castle_id, 20, gc->Ghp2);
+ Ghp[i][2] = gc->Ghp2;
+ }
+ if (gc->visibleG3 == 1 && Ghp[i][3] != gc->Ghp3) {
+ guild_castledatasave(gc->castle_id, 21, gc->Ghp3);
+ Ghp[i][3] = gc->Ghp3;
+ }
+ if (gc->visibleG4 == 1 && Ghp[i][4] != gc->Ghp4) {
+ guild_castledatasave(gc->castle_id, 22, gc->Ghp4);
+ Ghp[i][4] = gc->Ghp4;
+ }
+ if (gc->visibleG5 == 1 && Ghp[i][5] != gc->Ghp5) {
+ guild_castledatasave(gc->castle_id, 23, gc->Ghp5);
+ Ghp[i][5] = gc->Ghp5;
+ }
+ if (gc->visibleG6 == 1 && Ghp[i][6] != gc->Ghp6) {
+ guild_castledatasave(gc->castle_id, 24, gc->Ghp6);
+ Ghp[i][6] = gc->Ghp6;
+ }
+ if (gc->visibleG7 == 1 && Ghp[i][7] != gc->Ghp7) {
+ guild_castledatasave(gc->castle_id, 25, gc->Ghp7);
+ Ghp[i][7] = gc->Ghp7;
+ }
+ }
+
return 0;
}
@@ -1469,7 +1616,7 @@ int guild_agit_break(struct mob_data *md)
nullpo_retr(0, md);
- evname=(char *)aCalloc(strlen(md->npc_event) + 1, sizeof(char));
+ evname=(char *)aCallocA(strlen(md->npc_event) + 1, sizeof(char));
strcpy(evname,md->npc_event);
// Now By User to Run [OnAgitBreak] NPC Event...
@@ -1491,7 +1638,7 @@ int guild_checkcastles(struct guild *g) {
for(i=0;i<MAX_GUILDCASTLE;i++){
gc=guild_castle_search(i);
cas_id=gc->guild_id;
- if(g->guild_id==cas_id)
+ if(g->guild_id==cas_id)
nb_cas=nb_cas+1;
} //end for
return nb_cas;
@@ -1522,36 +1669,36 @@ int guild_isallied(struct guild *g, struct guild_castle *gc)
return 0;
}
-
+
static int guild_db_final(void *key,void *data,va_list ap)
{
- struct guild *g=data;
+ struct guild *g=(struct guild *) data;
- free(g);
+ aFree(g);
return 0;
}
static int castle_db_final(void *key,void *data,va_list ap)
{
- struct guild_castle *gc=data;
+ struct guild_castle *gc=(struct guild_castle *) data;
- free(gc);
+ aFree(gc);
return 0;
}
static int guild_expcache_db_final(void *key,void *data,va_list ap)
{
- struct guild_expcache *c=data;
+ struct guild_expcache *c=(struct guild_expcache *) data;
- free(c);
+ aFree(c);
return 0;
}
static int guild_infoevent_db_final(void *key,void *data,va_list ap)
{
- struct eventlist *ev=data;
+ struct eventlist *ev=(struct eventlist *) data;
- free(ev);
+ aFree(ev);
return 0;
}
diff --git a/src/map/guild.h b/src/map/guild.h
index 528605f7f..1dee350a1 100644
--- a/src/map/guild.h
+++ b/src/map/guild.h
@@ -29,6 +29,7 @@ struct map_session_data *guild_getavailablesd(struct guild *g);
int guild_getindex(struct guild *g,int account_id,int char_id);
int guild_getposition(struct map_session_data *sd,struct guild *g);
int guild_payexp(struct map_session_data *sd,int exp);
+int guild_getexp(struct map_session_data *sd,int exp); // [Celest]
int guild_create(struct map_session_data *sd,char *name);
int guild_created(int account_id,int guild_id);
@@ -53,9 +54,10 @@ int guild_allianceack(int guild_id1,int guild_id2,int account_id1,int account_id
int flag,const char *name1,const char *name2);
int guild_delalliance(struct map_session_data *sd,int guild_id,int flag);
int guild_opposition(struct map_session_data *sd,int char_id);
+int guild_check_alliance(int guild_id1, int guild_id2, int flag);
int guild_send_memberinfoshort(struct map_session_data *sd,int online);
-int guild_recv_memberinfoshort(int guild_id,int account_id,int char_id,int online,int lv,int class);
+int guild_recv_memberinfoshort(int guild_id,int account_id,int char_id,int online,int lv,int class_);
int guild_change_memberposition(int guild_id,int account_id,int char_id,int idx);
int guild_memberposition_changed(struct guild *g,int idx,int pos);
int guild_change_position(struct map_session_data *sd,int idx,
diff --git a/src/map/intif.c b/src/map/intif.c
index fc79e5148..3aa472ad8 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -31,6 +31,7 @@
#include "guild.h"
#include "pet.h"
#include "nullpo.h"
+#include "malloc.h"
#ifdef MEMWATCH
#include "memwatch.h"
@@ -54,10 +55,16 @@ extern int char_fd; // inter server‚Ìfd‚Íchar_fd‚ðŽg‚¤
//-----------------------------------------------------------------
// inter server‚Ö‚Ì‘—M
+int CheckForCharServer() {
+ return ((char_fd == -1) || session[char_fd] == NULL || session[char_fd]->wdata == NULL);
+}
+
// pet
int intif_create_pet(int account_id,int char_id,short pet_class,short pet_lv,short pet_egg_id,
short pet_equip,short intimate,short hungry,char rename_flag,char incuvate,char *pet_name)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0) = 0x3080;
WFIFOL(inter_fd,2) = account_id;
WFIFOL(inter_fd,6) = char_id;
@@ -77,6 +84,8 @@ int intif_create_pet(int account_id,int char_id,short pet_class,short pet_lv,sho
int intif_request_petdata(int account_id,int char_id,int pet_id)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0) = 0x3081;
WFIFOL(inter_fd,2) = account_id;
WFIFOL(inter_fd,6) = char_id;
@@ -88,6 +97,8 @@ int intif_request_petdata(int account_id,int char_id,int pet_id)
int intif_save_petdata(int account_id,struct s_pet *p)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0) = 0x3082;
WFIFOW(inter_fd,2) = sizeof(struct s_pet) + 8;
WFIFOL(inter_fd,4) = account_id;
@@ -99,6 +110,8 @@ int intif_save_petdata(int account_id,struct s_pet *p)
int intif_delete_petdata(int pet_id)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0) = 0x3083;
WFIFOL(inter_fd,2) = pet_id;
WFIFOSET(inter_fd,6);
@@ -110,18 +123,25 @@ int intif_delete_petdata(int pet_id)
int intif_GMmessage(char* mes,int len,int flag)
{
int lp = (flag&0x10) ? 8 : 4;
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0) = 0x3000;
WFIFOW(inter_fd,2) = lp + len;
WFIFOL(inter_fd,4) = 0x65756c62;
memcpy(WFIFOP(inter_fd,lp), mes, len);
WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
+ // Send to the local players
+ clif_GMmessage(NULL, mes, len, 0);
+
return 0;
}
// The transmission of Wisp/Page to inter-server (player not found on this server)
int intif_wis_message(struct map_session_data *sd, char *nick, char *mes, int mes_len) {
nullpo_retr(0, sd);
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0) = 0x3001;
WFIFOW(inter_fd,2) = mes_len + 52;
@@ -138,6 +158,8 @@ int intif_wis_message(struct map_session_data *sd, char *nick, char *mes, int me
// The reply of Wisp/page
int intif_wis_replay(int id, int flag) {
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0) = 0x3002;
WFIFOL(inter_fd,2) = id;
WFIFOB(inter_fd,6) = flag; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
@@ -150,7 +172,11 @@ int intif_wis_replay(int id, int flag) {
}
// The transmission of GM only Wisp/Page from server to inter-server
-int intif_wis_message_to_gm(char *Wisp_name, int min_gm_level, char *mes, int mes_len) {
+int intif_wis_message_to_gm(char *Wisp_name, int min_gm_level, char *mes) {
+ int mes_len;
+ if (CheckForCharServer())
+ return 0;
+ mes_len = strlen(mes) + 1; // + null
WFIFOW(inter_fd,0) = 0x3003;
WFIFOW(inter_fd,2) = mes_len + 30;
memcpy(WFIFOP(inter_fd,4), Wisp_name, 24);
@@ -167,9 +193,14 @@ int intif_wis_message_to_gm(char *Wisp_name, int min_gm_level, char *mes, int me
// ƒAƒJƒEƒ“ƒg•Ï”‘—M
int intif_saveaccountreg(struct map_session_data *sd) {
int j,p;
+ if (CheckForCharServer())
+ return 0;
nullpo_retr(0, sd);
+ if (sd->status.account_reg_num == -1)
+ return 0;
+
WFIFOW(inter_fd,0) = 0x3004;
WFIFOL(inter_fd,4) = sd->bl.id;
for(j=0,p=8;j<sd->status.account_reg_num;j++,p+=36){
@@ -184,16 +215,23 @@ int intif_saveaccountreg(struct map_session_data *sd) {
int intif_request_accountreg(struct map_session_data *sd)
{
nullpo_retr(0, sd);
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0) = 0x3005;
WFIFOL(inter_fd,2) = sd->bl.id;
WFIFOSET(inter_fd,6);
+
+ sd->status.account_reg_num = -1;
+
return 0;
}
// ‘qŒÉƒf[ƒ^—v‹
int intif_request_storage(int account_id)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0) = 0x3010;
WFIFOL(inter_fd,2) = account_id;
WFIFOSET(inter_fd,6);
@@ -202,6 +240,8 @@ int intif_request_storage(int account_id)
// ‘qŒÉƒf[ƒ^‘—M
int intif_send_storage(struct storage *stor)
{
+ if (CheckForCharServer())
+ return 0;
nullpo_retr(0, stor);
WFIFOW(inter_fd,0) = 0x3011;
WFIFOW(inter_fd,2) = sizeof(struct storage)+8;
@@ -213,6 +253,8 @@ int intif_send_storage(struct storage *stor)
int intif_request_guild_storage(int account_id,int guild_id)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0) = 0x3018;
WFIFOL(inter_fd,2) = account_id;
WFIFOL(inter_fd,6) = guild_id;
@@ -221,6 +263,8 @@ int intif_request_guild_storage(int account_id,int guild_id)
}
int intif_send_guild_storage(int account_id,struct guild_storage *gstor)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0) = 0x3019;
WFIFOW(inter_fd,2) = sizeof(struct guild_storage)+12;
WFIFOL(inter_fd,4) = account_id;
@@ -231,8 +275,10 @@ int intif_send_guild_storage(int account_id,struct guild_storage *gstor)
}
// ƒp[ƒeƒB쬗v‹
-int intif_create_party(struct map_session_data *sd,char *name)
+int intif_create_party(struct map_session_data *sd,char *name,int item,int item2)
{
+ if (CheckForCharServer())
+ return 0;
nullpo_retr(0, sd);
WFIFOW(inter_fd,0) = 0x3020;
@@ -241,7 +287,9 @@ int intif_create_party(struct map_session_data *sd,char *name)
memcpy(WFIFOP(inter_fd,30),sd->status.name,24);
memcpy(WFIFOP(inter_fd,54),map[sd->bl.m].name,16);
WFIFOW(inter_fd,70)= sd->status.base_level;
- WFIFOSET(inter_fd,72);
+ WFIFOB(inter_fd,72)= item;
+ WFIFOB(inter_fd,73)= item2;
+ WFIFOSET(inter_fd,74);
// if(battle_config.etc_log)
// printf("intif: create party\n");
return 0;
@@ -249,6 +297,8 @@ int intif_create_party(struct map_session_data *sd,char *name)
// ƒp[ƒeƒBî•ñ—v‹
int intif_request_partyinfo(int party_id)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0) = 0x3021;
WFIFOL(inter_fd,2) = party_id;
WFIFOSET(inter_fd,6);
@@ -260,6 +310,8 @@ int intif_request_partyinfo(int party_id)
int intif_party_addmember(int party_id,int account_id)
{
struct map_session_data *sd;
+ if (CheckForCharServer())
+ return 0;
sd=map_id2sd(account_id);
// if(battle_config.etc_log)
// printf("intif: party add member %d %d\n",party_id,account_id);
@@ -277,6 +329,8 @@ int intif_party_addmember(int party_id,int account_id)
// ƒp[ƒeƒBÝ’è•ÏX
int intif_party_changeoption(int party_id,int account_id,int exp,int item)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0)=0x3023;
WFIFOL(inter_fd,2)=party_id;
WFIFOL(inter_fd,6)=account_id;
@@ -288,6 +342,8 @@ int intif_party_changeoption(int party_id,int account_id,int exp,int item)
// ƒp[ƒeƒB’E‘Þ—v‹
int intif_party_leave(int party_id,int account_id)
{
+ if (CheckForCharServer())
+ return 0;
// if(battle_config.etc_log)
// printf("intif: party leave %d %d\n",party_id,account_id);
WFIFOW(inter_fd,0)=0x3024;
@@ -299,6 +355,8 @@ int intif_party_leave(int party_id,int account_id)
// ƒp[ƒeƒBˆÚ“®—v‹
int intif_party_changemap(struct map_session_data *sd,int online)
{
+ if (CheckForCharServer())
+ return 0;
if(sd!=NULL){
WFIFOW(inter_fd,0)=0x3025;
WFIFOL(inter_fd,2)=sd->status.party_id;
@@ -315,6 +373,8 @@ int intif_party_changemap(struct map_session_data *sd,int online)
// ƒp[ƒeƒB[‰ðŽU—v‹
int intif_break_party(int party_id)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0)=0x3026;
WFIFOL(inter_fd,2)=party_id;
WFIFOSET(inter_fd,6);
@@ -323,6 +383,8 @@ int intif_break_party(int party_id)
// ƒp[ƒeƒB‰ï˜b‘—M
int intif_party_message(int party_id,int account_id,char *mes,int len)
{
+ if (CheckForCharServer())
+ return 0;
// if(battle_config.etc_log)
// printf("intif_party_message: %s\n",mes);
WFIFOW(inter_fd,0)=0x3027;
@@ -336,6 +398,8 @@ int intif_party_message(int party_id,int account_id,char *mes,int len)
// ƒp[ƒeƒB‹£‡ƒ`ƒFƒbƒN—v‹
int intif_party_checkconflict(int party_id,int account_id,char *nick)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0)=0x3028;
WFIFOL(inter_fd,2)=party_id;
WFIFOL(inter_fd,6)=account_id;
@@ -347,6 +411,8 @@ int intif_party_checkconflict(int party_id,int account_id,char *nick)
// ƒMƒ‹ƒh쬗v‹
int intif_guild_create(const char *name,const struct guild_member *master)
{
+ if (CheckForCharServer())
+ return 0;
nullpo_retr(0, master);
WFIFOW(inter_fd,0)=0x3030;
@@ -360,6 +426,8 @@ int intif_guild_create(const char *name,const struct guild_member *master)
// ƒMƒ‹ƒhî•ñ—v‹
int intif_guild_request_info(int guild_id)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0) = 0x3031;
WFIFOL(inter_fd,2) = guild_id;
WFIFOSET(inter_fd,6);
@@ -368,6 +436,8 @@ int intif_guild_request_info(int guild_id)
// ƒMƒ‹ƒhƒƒ“ƒo’ljÁ—v‹
int intif_guild_addmember(int guild_id,struct guild_member *m)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0) = 0x3032;
WFIFOW(inter_fd,2) = sizeof(struct guild_member)+8;
WFIFOL(inter_fd,4) = guild_id;
@@ -378,6 +448,8 @@ int intif_guild_addmember(int guild_id,struct guild_member *m)
// ƒMƒ‹ƒhƒƒ“ƒo’E‘Þ/’Ç•ú—v‹
int intif_guild_leave(int guild_id,int account_id,int char_id,int flag,const char *mes)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd, 0) = 0x3034;
WFIFOL(inter_fd, 2) = guild_id;
WFIFOL(inter_fd, 6) = account_id;
@@ -389,21 +461,25 @@ int intif_guild_leave(int guild_id,int account_id,int char_id,int flag,const cha
}
// ƒMƒ‹ƒhƒƒ“ƒo‚̃Iƒ“ƒ‰ƒCƒ“ó‹µ/LvXV—v‹
int intif_guild_memberinfoshort(int guild_id,
- int account_id,int char_id,int online,int lv,int class)
+ int account_id,int char_id,int online,int lv,int class_)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd, 0) = 0x3035;
WFIFOL(inter_fd, 2) = guild_id;
WFIFOL(inter_fd, 6) = account_id;
WFIFOL(inter_fd,10) = char_id;
WFIFOB(inter_fd,14) = online;
WFIFOW(inter_fd,15) = lv;
- WFIFOW(inter_fd,17) = class;
+ WFIFOW(inter_fd,17) = class_;
WFIFOSET(inter_fd,19);
return 0;
}
// ƒMƒ‹ƒh‰ðŽU’Ê’m
int intif_guild_break(int guild_id)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd, 0) = 0x3036;
WFIFOL(inter_fd, 2) = guild_id;
WFIFOSET(inter_fd,6);
@@ -412,17 +488,22 @@ int intif_guild_break(int guild_id)
// ƒMƒ‹ƒh‰ï˜b‘—M
int intif_guild_message(int guild_id,int account_id,char *mes,int len)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0)=0x3037;
WFIFOW(inter_fd,2)=len+12;
WFIFOL(inter_fd,4)=guild_id;
WFIFOL(inter_fd,8)=account_id;
memcpy(WFIFOP(inter_fd,12),mes,len);
WFIFOSET(inter_fd,len+12);
+
return 0;
}
// ƒMƒ‹ƒh‹£‡ƒ`ƒFƒbƒN—v‹
int intif_guild_checkconflict(int guild_id,int account_id,int char_id)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd, 0)=0x3038;
WFIFOL(inter_fd, 2)=guild_id;
WFIFOL(inter_fd, 6)=account_id;
@@ -433,6 +514,8 @@ int intif_guild_checkconflict(int guild_id,int account_id,int char_id)
// ƒMƒ‹ƒhŠî–{î•ñ•ÏX—v‹
int intif_guild_change_basicinfo(int guild_id,int type,const void *data,int len)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0)=0x3039;
WFIFOW(inter_fd,2)=len+10;
WFIFOL(inter_fd,4)=guild_id;
@@ -445,6 +528,8 @@ int intif_guild_change_basicinfo(int guild_id,int type,const void *data,int len)
int intif_guild_change_memberinfo(int guild_id,int account_id,int char_id,
int type,const void *data,int len)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd, 0)=0x303a;
WFIFOW(inter_fd, 2)=len+18;
WFIFOL(inter_fd, 4)=guild_id;
@@ -458,6 +543,8 @@ int intif_guild_change_memberinfo(int guild_id,int account_id,int char_id,
// ƒMƒ‹ƒh–ðE•ÏX—v‹
int intif_guild_position(int guild_id,int idx,struct guild_position *p)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0)=0x303b;
WFIFOW(inter_fd,2)=sizeof(struct guild_position)+12;
WFIFOL(inter_fd,4)=guild_id;
@@ -469,6 +556,8 @@ int intif_guild_position(int guild_id,int idx,struct guild_position *p)
// ƒMƒ‹ƒhƒXƒLƒ‹ƒAƒbƒv—v‹
int intif_guild_skillup(int guild_id,int skill_num,int account_id,int flag)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd, 0)=0x303c;
WFIFOL(inter_fd, 2)=guild_id;
WFIFOL(inter_fd, 6)=skill_num;
@@ -480,6 +569,8 @@ int intif_guild_skillup(int guild_id,int skill_num,int account_id,int flag)
// ƒMƒ‹ƒh“¯–¿/“G‘Ηv‹
int intif_guild_alliance(int guild_id1,int guild_id2,int account_id1,int account_id2,int flag)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd, 0)=0x303d;
WFIFOL(inter_fd, 2)=guild_id1;
WFIFOL(inter_fd, 6)=guild_id2;
@@ -492,6 +583,8 @@ int intif_guild_alliance(int guild_id1,int guild_id2,int account_id1,int account
// ƒMƒ‹ƒh’m•ÏX—v‹
int intif_guild_notice(int guild_id,const char *mes1,const char *mes2)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0)=0x303e;
WFIFOL(inter_fd,2)=guild_id;
memcpy(WFIFOP(inter_fd,6),mes1,60);
@@ -502,6 +595,8 @@ int intif_guild_notice(int guild_id,const char *mes1,const char *mes2)
// ƒMƒ‹ƒhƒGƒ“ƒuƒŒƒ€•ÏX—v‹
int intif_guild_emblem(int guild_id,int len,const char *data)
{
+ if (CheckForCharServer())
+ return 0;
if(guild_id<=0 || len<0 || len>2000)
return 0;
WFIFOW(inter_fd,0)=0x303f;
@@ -515,6 +610,8 @@ int intif_guild_emblem(int guild_id,int len,const char *data)
//Œ»Ý‚̃Mƒ‹ƒhéè—̃Mƒ‹ƒh‚𒲂ׂé
int intif_guild_castle_dataload(int castle_id,int index)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0)=0x3040;
WFIFOW(inter_fd,2)=castle_id;
WFIFOB(inter_fd,4)=index;
@@ -525,6 +622,8 @@ int intif_guild_castle_dataload(int castle_id,int index)
//ƒMƒ‹ƒhéè—̃Mƒ‹ƒh•ÏX—v‹
int intif_guild_castle_datasave(int castle_id,int index, int value)
{
+ if (CheckForCharServer())
+ return 0;
WFIFOW(inter_fd,0)=0x3041;
WFIFOW(inter_fd,2)=castle_id;
WFIFOB(inter_fd,4)=index;
@@ -539,14 +638,15 @@ int intif_guild_castle_datasave(int castle_id,int index, int value)
// Wisp/Page reception
int intif_parse_WisMessage(int fd) { // rewritten by [Yor]
struct map_session_data* sd;
+ char *wisp_source;
int id=RFIFOL(fd,4);
int i=0; //,j=0;
// if(battle_config.etc_log)
// printf("intif_parse_wismessage: %d %s %s %s\n",id,RFIFOP(fd,6),RFIFOP(fd,30),RFIFOP(fd,54) );
-
- sd=map_nick2sd(RFIFOP(fd,32)); // ‘—Mæ‚ð’T‚·
- if(sd!=NULL && strcmp(sd->status.name, RFIFOP(fd,32)) == 0){
+
+ sd=(struct map_session_data *) map_nick2sd((char *) RFIFOP(fd,32)); // ‘—Mæ‚ð’T‚·
+ if(sd!=NULL && strcmp((char *) sd->status.name, (char *) RFIFOP(fd,32)) == 0){
/*
for(i=0;i<MAX_WIS_REFUSAL;i++){ //‹‘”ÛƒŠƒXƒg‚É–¼‘O‚ª‚ ‚é‚©‚Ç‚¤‚©”»’肵‚Ä‚ ‚ê‚΋‘”Û
if(strcmp(sd->wis_refusal[i],RFIFOP(fd,8))==0){
@@ -563,9 +663,20 @@ int intif_parse_WisMessage(int fd) { // rewritten by [Yor]
else{
*/
- if(i == MAX_IGNORE_LIST) {
- clif_wis_message(sd->fd,RFIFOP(fd,8),RFIFOP(fd,56),RFIFOW(fd,2)-56);
- intif_wis_replay(RFIFOL(fd,4),0); // ‘—M¬Œ÷
+ else {
+ wisp_source = (char *) RFIFOP(fd,8); // speed up [Yor]
+ for(i=0;i<MAX_IGNORE_LIST;i++){ //‹‘”ÛƒŠƒXƒg‚É–¼‘O‚ª‚ ‚é‚©‚Ç‚¤‚©”»’肵‚Ä‚ ‚ê‚΋‘”Û
+ if(strcmp(sd->ignore[i].name, wisp_source)==0){
+ break;
+ }
+ }
+ if(i==MAX_IGNORE_LIST) // run out of list, so we are not ignored
+ {
+ clif_wis_message(sd->fd, wisp_source, (char*)RFIFOP(fd,56),RFIFOW(fd,2)-56);
+ intif_wis_replay(id,0); // ‘—M¬Œ÷
+ }
+ else
+ intif_wis_replay(id, 2); // ŽóM‹‘”Û
}
}else
intif_wis_replay(id,1); // ‚»‚ñ‚Èl‚¢‚Ü‚¹‚ñ
@@ -578,7 +689,7 @@ int intif_parse_WisEnd(int fd) {
if (battle_config.etc_log)
printf("intif_parse_wisend: player: %s, flag: %d\n", RFIFOP(fd,2), RFIFOB(fd,26)); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
- sd = map_nick2sd(RFIFOP(fd,2));
+ sd = (struct map_session_data *)map_nick2sd((char *) RFIFOP(fd,2));
if (sd != NULL)
clif_wis_end(sd->fd, RFIFOB(fd,26));
@@ -591,7 +702,7 @@ int mapif_parse_WisToGM(int fd) { // 0x3003/0x3803 <packet_len>.w <wispname>.24B
struct map_session_data *pl_sd;
char Wisp_name[24];
char mbuf[255];
- char *message = ((RFIFOW(fd,2) - 30) >= sizeof(mbuf)) ? (char *) malloc((RFIFOW(fd,2) - 30)) : mbuf;
+ char *message = (char *) (((RFIFOW(fd,2) - 30) >= sizeof(mbuf)) ? (char *) aMallocA((RFIFOW(fd,2) - 30)) : mbuf);
min_gm_level = (int)RFIFOW(fd,28);
memcpy(Wisp_name, RFIFOP(fd,4), 24);
@@ -600,12 +711,12 @@ int mapif_parse_WisToGM(int fd) { // 0x3003/0x3803 <packet_len>.w <wispname>.24B
message[sizeof(message) - 1] = '\0';
// information is sended to all online GM
for (i = 0; i < fd_max; i++)
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth)
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth)
if (pc_isGM(pl_sd) >= min_gm_level)
clif_wis_message(i, Wisp_name, message, strlen(message) + 1);
if (message != mbuf)
- free(message);
+ aFree(message);
return 0;
}
@@ -633,6 +744,13 @@ int intif_parse_LoadStorage(int fd) {
struct map_session_data *sd;
stor = account2storage( RFIFOL(fd,4));
+
+ if (stor->storage_status == 1) { // Already open.. lets ignore this update
+ if (battle_config.error_log)
+ printf("intif_parse_LoadStorage: storage received for a client already open\n");
+ return 0;
+ }
+
if (RFIFOW(fd,2)-8 != sizeof(struct storage)) {
if (battle_config.error_log)
printf("intif_parse_LoadStorage: data size error %d %d\n", RFIFOW(fd,2)-8, sizeof(struct storage));
@@ -647,6 +765,7 @@ int intif_parse_LoadStorage(int fd) {
if(battle_config.save_log)
printf("intif_openstorage: %d\n",RFIFOL(fd,4) );
memcpy(stor,RFIFOP(fd,8),sizeof(struct storage));
+ stor->dirty=0;
stor->storage_status=1;
sd->state.storage_flag = 0;
clif_storageitemlist(sd,stor);
@@ -712,7 +831,7 @@ int intif_parse_PartyCreated(int fd)
{
if(battle_config.etc_log)
printf("intif: party created\n");
- party_created(RFIFOL(fd,2),RFIFOB(fd,6),RFIFOL(fd,7),RFIFOP(fd,11));
+ party_created(RFIFOL(fd,2), RFIFOB(fd,6),RFIFOL(fd,7),(char *) RFIFOP(fd,11));
return 0;
}
// ƒp[ƒeƒBî•ñ
@@ -752,7 +871,7 @@ int intif_parse_PartyMemberLeaved(int fd)
{
if(battle_config.etc_log)
printf("intif: party member leaved %d %d %s\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOP(fd,10));
- party_member_leaved(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOP(fd,10));
+ party_member_leaved(RFIFOL(fd,2),RFIFOL(fd,6),(char *) RFIFOP(fd,10));
return 0;
}
// ƒp[ƒeƒB‰ðŽU’Ê’m
@@ -766,7 +885,7 @@ int intif_parse_PartyMove(int fd)
{
// if(battle_config.etc_log)
// printf("intif: party move %d %d %s %d %d\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOP(fd,10),RFIFOB(fd,26),RFIFOW(fd,27));
- party_recv_movemap(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOP(fd,10),RFIFOB(fd,26),RFIFOW(fd,27));
+ party_recv_movemap(RFIFOL(fd,2),RFIFOL(fd,6),(char *) RFIFOP(fd,10),RFIFOB(fd,26),RFIFOW(fd,27));
return 0;
}
// ƒp[ƒeƒBƒƒbƒZ[ƒW
@@ -774,7 +893,7 @@ int intif_parse_PartyMessage(int fd)
{
// if(battle_config.etc_log)
// printf("intif_parse_PartyMessage: %s\n",RFIFOP(fd,12));
- party_recv_message(RFIFOL(fd,4),RFIFOL(fd,8),RFIFOP(fd,12),RFIFOW(fd,2)-12);
+ party_recv_message(RFIFOL(fd,4),RFIFOL(fd,8),(char *) RFIFOP(fd,12),RFIFOW(fd,2)-12);
return 0;
}
@@ -815,7 +934,7 @@ int intif_parse_GuildMemberAdded(int fd)
int intif_parse_GuildMemberLeaved(int fd)
{
guild_member_leaved(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14),
- RFIFOP(fd,55),RFIFOP(fd,15));
+ (char *) RFIFOP(fd,55), (char *) RFIFOP(fd,15));
return 0;
}
@@ -892,25 +1011,25 @@ int intif_parse_GuildSkillUp(int fd)
int intif_parse_GuildAlliance(int fd)
{
guild_allianceack(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOL(fd,14),
- RFIFOB(fd,18),RFIFOP(fd,19),RFIFOP(fd,43));
+ RFIFOB(fd,18),(char *) RFIFOP(fd,19),(char *) RFIFOP(fd,43));
return 0;
}
// ƒMƒ‹ƒh’m•ÏX’Ê’m
int intif_parse_GuildNotice(int fd)
{
- guild_notice_changed(RFIFOL(fd,2),RFIFOP(fd,6),RFIFOP(fd,66));
+ guild_notice_changed(RFIFOL(fd,2),(char *) RFIFOP(fd,6),(char *) RFIFOP(fd,66));
return 0;
}
// ƒMƒ‹ƒhƒGƒ“ƒuƒŒƒ€•ÏX’Ê’m
int intif_parse_GuildEmblem(int fd)
{
- guild_emblem_changed(RFIFOW(fd,2)-12,RFIFOL(fd,4),RFIFOL(fd,8),RFIFOP(fd,12));
+ guild_emblem_changed(RFIFOW(fd,2)-12,RFIFOL(fd,4),RFIFOL(fd,8), (char *)RFIFOP(fd,12));
return 0;
}
// ƒMƒ‹ƒh‰ï˜bŽóM
int intif_parse_GuildMessage(int fd)
{
- guild_recv_message(RFIFOL(fd,4),RFIFOL(fd,8),RFIFOP(fd,12),RFIFOW(fd,2)-12);
+ guild_recv_message(RFIFOL(fd,4),RFIFOL(fd,8),(char *) RFIFOP(fd,12),RFIFOW(fd,2)-12);
return 0;
}
// ƒMƒ‹ƒhéƒf[ƒ^—v‹•ÔM
@@ -999,7 +1118,7 @@ int intif_parse(int fd)
}
// ˆ—•ªŠò
switch(cmd){
- case 0x3800: clif_GMmessage(NULL,RFIFOP(fd,4),packet_len-4,0); break;
+ case 0x3800: clif_GMmessage(NULL,(char *) RFIFOP(fd,4),packet_len-4,0); break;
case 0x3801: intif_parse_WisMessage(fd); break;
case 0x3802: intif_parse_WisEnd(fd); break;
case 0x3803: mapif_parse_WisToGM(fd); break;
diff --git a/src/map/intif.h b/src/map/intif.h
index 5077dbe18..17d6045ac 100644
--- a/src/map/intif.h
+++ b/src/map/intif.h
@@ -7,7 +7,7 @@ int intif_parse(int fd);
int intif_GMmessage(char* mes,int len,int flag);
int intif_wis_message(struct map_session_data *sd,char *nick,char *mes,int mes_len);
-int intif_wis_message_to_gm(char *Wisp_name, int min_gm_level, char *mes, int mes_len);
+int intif_wis_message_to_gm(char *Wisp_name, int min_gm_level, char *mes);
int intif_saveaccountreg(struct map_session_data *sd);
int intif_request_accountreg(struct map_session_data *sd);
@@ -18,7 +18,7 @@ int intif_request_guild_storage(int account_id, int guild_id);
int intif_send_guild_storage(int account_id, struct guild_storage *gstor);
-int intif_create_party(struct map_session_data *sd,char *name);
+int intif_create_party(struct map_session_data *sd,char *name,int item,int item2);
int intif_request_partyinfo(int party_id);
int intif_party_addmember(int party_id, int account_id);
int intif_party_changeoption(int party_id, int account_id, int exp, int item);
@@ -33,7 +33,7 @@ int intif_guild_create(const char *name, const struct guild_member *master);
int intif_guild_request_info(int guild_id);
int intif_guild_addmember(int guild_id, struct guild_member *m);
int intif_guild_leave(int guild_id, int account_id, int char_id, int flag, const char *mes);
-int intif_guild_memberinfoshort(int guild_id, int account_id, int char_id, int online, int lv, int class);
+int intif_guild_memberinfoshort(int guild_id, int account_id, int char_id, int online, int lv, int class_);
int intif_guild_break(int guild_id);
int intif_guild_message(int guild_id, int account_id, char *mes, int len);
int intif_guild_checkconflict(int guild_id, int account_id, int char_id);
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index a225cff83..91ec58c81 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -12,6 +12,7 @@
#include "itemdb.h"
#include "script.h"
#include "pc.h"
+#include "showmsg.h"
#ifdef MEMWATCH
#include "memwatch.h"
@@ -25,9 +26,9 @@
static struct dbt* item_db;
-static struct random_item_data blue_box[MAX_RANDITEM],violet_box[MAX_RANDITEM],card_album[MAX_RANDITEM],gift_box[MAX_RANDITEM],scroll[MAX_RANDITEM];
-static int blue_box_count=0,violet_box_count=0,card_album_count=0,gift_box_count=0,scroll_count=0;
-static int blue_box_default=0,violet_box_default=0,card_album_default=0,gift_box_default=0,scroll_default=0;
+static struct random_item_data blue_box[MAX_RANDITEM], violet_box[MAX_RANDITEM], card_album[MAX_RANDITEM], gift_box[MAX_RANDITEM], scroll[MAX_RANDITEM], finding_ore[MAX_RANDITEM];
+static int blue_box_count=0, violet_box_count=0, card_album_count=0, gift_box_count=0, scroll_count=0, finding_ore_count = 0;
+static int blue_box_default=0, violet_box_default=0, card_album_default=0, gift_box_default=0, scroll_default=0, finding_ore_default = 0;
// Function declarations
@@ -39,7 +40,11 @@ static int itemdb_read_sqldb(void);
static int itemdb_read_randomitem();
static int itemdb_read_itemavail(void);
static int itemdb_read_itemnametable(void);
+static int itemdb_read_itemslottable(void);
+static int itemdb_read_itemslotcounttable(void);
+static int itemdb_read_cardillustnametable(void);
static int itemdb_read_noequip(void);
+static int itemdb_read_norefine(void);
void itemdb_reload(void);
/*==========================================
@@ -97,16 +102,18 @@ int itemdb_searchrandomid(int flags)
struct {
int nameid,count;
struct random_item_data *list;
- } data[] ={
- { 0,0,NULL },
- { blue_box_default ,blue_box_count ,blue_box },
- { violet_box_default,violet_box_count ,violet_box },
- { card_album_default,card_album_count ,card_album },
- { gift_box_default ,gift_box_count ,gift_box },
- { scroll_default ,scroll_count ,scroll },
- };
-
- if(flags>=1 && flags<=5){
+ } data[7];
+
+ // for BCC32 compile error
+ data[0].nameid = 0; data[0].count = 0; data[0].list = NULL;
+ data[1].nameid = blue_box_default; data[1].count = blue_box_count; data[1].list = blue_box;
+ data[2].nameid = violet_box_default; data[2].count = violet_box_count; data[2].list = violet_box;
+ data[3].nameid = card_album_default; data[3].count = card_album_count; data[3].list = card_album;
+ data[4].nameid = gift_box_default; data[4].count = gift_box_count; data[4].list = gift_box;
+ data[5].nameid = scroll_default; data[5].count = scroll_count; data[5].list = scroll;
+ data[6].nameid = finding_ore_default; data[6].count = finding_ore_count; data[6].list = finding_ore;
+
+ if(flags>=1 && flags<=6){
nameid=data[flags].nameid;
count=data[flags].count;
list=data[flags].list;
@@ -130,7 +137,7 @@ int itemdb_searchrandomid(int flags)
*/
struct item_data* itemdb_exists(int nameid)
{
- return numdb_search(item_db,nameid);
+ return (struct item_data *) numdb_search(item_db,nameid);
}
/*==========================================
* DB‚ÌŒŸõ
@@ -140,7 +147,7 @@ struct item_data* itemdb_search(int nameid)
{
struct item_data *id;
- id=numdb_search(item_db,nameid);
+ id=(struct item_data *) numdb_search(item_db,nameid);
if(id) return id;
id=(struct item_data *)aCalloc(1,sizeof(struct item_data));
@@ -152,7 +159,7 @@ struct item_data* itemdb_search(int nameid)
id->weight=10;
id->sex=2;
id->elv=0;
- id->class=0xffffffff;
+ id->class_=0xffffffff;
id->flag.available=0;
id->flag.value_notdc=0; //ˆê‰žEEE
id->flag.value_notoc=0;
@@ -237,66 +244,40 @@ int itemdb_isdropable(int nameid)
return 1;
}
-//
-// ‰Šú‰»
-//
-/*==========================================
- *
- *------------------------------------------
- */
-static int itemdb_read_itemslottable(void)
-{
- char *buf,*p;
- int s;
-
- buf=grfio_read("data\\itemslottable.txt");
- if(buf==NULL)
- return -1;
- s=grfio_size("data\\itemslottable.txt");
- buf[s]=0;
- for(p=buf;p-buf<s;){
- int nameid,equip;
- sscanf(p,"%d#%d#",&nameid,&equip);
- itemdb_search(nameid)->equip=equip;
- p=strchr(p,10);
- if(!p) break;
- p++;
- p=strchr(p,10);
- if(!p) break;
- p++;
- }
- free(buf);
-
- return 0;
-}
-
-#ifndef TXT_ONLY
/*====================================
* Removed item_value_db, don't re-add
*------------------------------------
*/
static void itemdb_read(void)
{
- itemdb_read_itemslottable();
-
- if (db_use_sqldbs)
- {
- itemdb_read_sqldb();
- }
- else
- {
+ #ifndef TXT_ONLY
+ if (db_use_sqldbs)
+ {
+ itemdb_read_sqldb();
+ }
+ else
+ {
+ itemdb_readdb();
+ }
+ /* not TXT_ONLY */
+ #else
itemdb_readdb();
- }
+ #endif /* TXT_ONLY */
itemdb_read_randomitem();
itemdb_read_itemavail();
itemdb_read_noequip();
-
- if (!battle_config.item_name_override_grffile)
+ itemdb_read_norefine();
+ if (battle_config.cardillust_read_grffile)
+ itemdb_read_cardillustnametable();
+ if (battle_config.item_equip_override_grffile)
+ itemdb_read_itemslottable();
+ if (battle_config.item_slots_override_grffile)
+ itemdb_read_itemslotcounttable();
+ if (battle_config.item_name_override_grffile)
itemdb_read_itemnametable();
}
-#endif /* not TXT_ONLY */
/*==========================================
* ƒAƒCƒeƒ€ƒf[ƒ^ƒx[ƒX‚̓ǂݞ‚Ý
*------------------------------------------
@@ -346,20 +327,36 @@ static int itemdb_readdb(void)
memcpy(id->name,str[1],24);
memcpy(id->jname,str[2],24);
id->type=atoi(str[3]);
- // buy‚sell*2 ‚Í item_value_db.txt ‚ÅŽw’肵‚Ä‚­‚¾‚³‚¢B
- if (atoi(str[5])) { // sell’l‚ð—Dæ‚Æ‚·‚é
- id->value_buy=atoi(str[5])*2;
- id->value_sell=atoi(str[5]);
- } else {
- id->value_buy=atoi(str[4]);
- id->value_sell=atoi(str[4])/2;
+
+ {
+ int buy = atoi(str[4]), sell = atoi(str[5]);
+ // if buying price > selling price * 2 consider it valid and don't change it [celest]
+ if (buy && sell && buy > sell*2){
+ id->value_buy = buy;
+ id->value_sell = sell;
+ } else {
+ // buy‚sell*2 ‚Í item_value_db.txt ‚ÅŽw’肵‚Ä‚­‚¾‚³‚¢B
+ if (sell) { // sell’l‚ð—Dæ‚Æ‚·‚é
+ id->value_buy = sell*2;
+ id->value_sell = sell;
+ } else {
+ id->value_buy = buy;
+ id->value_sell = buy/2;
+ }
+ }
+ // check for bad prices that can possibly cause exploits
+ if (id->value_buy*75/100 < id->value_sell*124/100) {
+ sprintf (tmp_output, "Item %s [%d] buying:%d < selling:%d\n",
+ id->name, id->nameid, id->value_buy*75/100, id->value_sell*124/100);
+ ShowWarning (tmp_output);
+ }
}
id->weight=atoi(str[6]);
id->atk=atoi(str[7]);
id->def=atoi(str[8]);
id->range=atoi(str[9]);
id->slot=atoi(str[10]);
- id->class=atoi(str[11]);
+ id->class_=atoi(str[11]);
id->sex=atoi(str[12]);
if(id->equip != atoi(str[13])){
id->equip=atoi(str[13]);
@@ -377,13 +374,17 @@ static int itemdb_readdb(void)
if((p=strchr(np,'{'))==NULL)
continue;
- id->use_script = parse_script(p,lines);
+ id->use_script = parse_script((unsigned char *) p,lines);
if((p=strchr(p+1,'{'))==NULL)
continue;
- id->equip_script = parse_script(p,lines);
+ id->equip_script = parse_script((unsigned char *) p,lines);
}
fclose(fp);
- printf("read %s done (count=%d)\n",filename[i],ln);
+ if (ln > 0) {
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,filename[i]);
+ ShowStatus(tmp_output);
+ }
+ ln=0; // reset to 0
}
return 0;
}
@@ -410,15 +411,16 @@ static int itemdb_read_randomitem()
{"db/item_bluebox.txt", blue_box, &blue_box_count, &blue_box_default },
{"db/item_violetbox.txt", violet_box, &violet_box_count, &violet_box_default },
{"db/item_cardalbum.txt", card_album, &card_album_count, &card_album_default },
- {"db/item_giftbox.txt", gift_box, &gift_box_count, &gift_box_default },
- {"db/item_scroll.txt", scroll, &scroll_count, &scroll_default },
+ {"db/item_giftbox.txt", gift_box, &gift_box_count, &gift_box_default },
+ {"db/item_scroll.txt", scroll, &scroll_count, &scroll_default },
+ {"db/item_findingore.txt", finding_ore,&finding_ore_count, &finding_ore_default },
};
for(i=0;i<sizeof(data)/sizeof(data[0]);i++){
struct random_item_data *pd=data[i].pdata;
int *pc=data[i].pcount;
int *pdefault=data[i].pdefault;
- char *fn=data[i].filename;
+ char *fn=(char *) data[i].filename;
*pdefault = 0;
if( (fp=fopen(fn,"r"))==NULL ){
@@ -458,7 +460,10 @@ static int itemdb_read_randomitem()
ln++;
}
fclose(fp);
- printf("read %s done (count=%d)\n",fn,*pc);
+ if (*pc > 0) {
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",*pc,fn);
+ ShowStatus(tmp_output);
+ }
}
return 0;
@@ -507,7 +512,8 @@ static int itemdb_read_itemavail(void)
ln++;
}
fclose(fp);
- printf("read db/item_avail.txt done (count=%d)\n",ln);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"db/item_avail.txt");
+ ShowStatus(tmp_output);
return 0;
}
@@ -520,7 +526,7 @@ static int itemdb_read_itemnametable(void)
char *buf,*p;
int s;
- buf=grfio_reads("data\\idnum2itemdisplaynametable.txt",&s);
+ buf=(char *) grfio_reads("data\\idnum2itemdisplaynametable.txt",&s);
if(buf==NULL)
return -1;
@@ -547,12 +553,13 @@ static int itemdb_read_itemnametable(void)
if(!p) break;
p++;
}
- free(buf);
- printf("read data\\idnum2itemdisplaynametable.txt done.\n");
+ aFree(buf);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","data\\idnum2itemdisplaynametable.txt");
+ ShowStatus(tmp_output);
return 0;
}
-#ifdef TXT_ONLY
+
/*==========================================
* ƒJ[ƒhƒCƒ‰ƒXƒg‚ÌƒŠƒ\[ƒX–¼‘Oƒe[ƒuƒ‹‚ð“ǂݞ‚Þ
*------------------------------------------
@@ -562,7 +569,7 @@ static int itemdb_read_cardillustnametable(void)
char *buf,*p;
int s;
- buf=grfio_reads("data\\num2cardillustnametable.txt",&s);
+ buf=(char *) grfio_reads("data\\num2cardillustnametable.txt",&s);
if(buf==NULL)
return -1;
@@ -582,12 +589,83 @@ static int itemdb_read_cardillustnametable(void)
if(!p) break;
p++;
}
- free(buf);
- printf("read data\\num2cardillustnametable.txt done.\n");
+ aFree(buf);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","data\\num2cardillustnametable.txt");
+ ShowStatus(tmp_output);
+
+ return 0;
+}
+
+//
+// ‰Šú‰»
+//
+/*==========================================
+ *
+ *------------------------------------------
+ */
+static int itemdb_read_itemslottable(void)
+{
+ char *buf,*p;
+ int s;
+
+ buf=(char *) grfio_read("data\\itemslottable.txt");
+ if(buf==NULL)
+ return -1;
+ s=grfio_size("data\\itemslottable.txt");
+ buf[s]=0;
+ for(p=buf;p-buf<s;){
+ int nameid,equip;
+ struct item_data* item;
+ sscanf(p,"%d#%d#",&nameid,&equip);
+ item = itemdb_search(nameid);
+ if (item && itemdb_isequip2(item))
+ item->equip=equip;
+ p=strchr(p,10);
+ if(!p) break;
+ p++;
+ p=strchr(p,10);
+ if(!p) break;
+ p++;
+ }
+ aFree(buf);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","data\\itemslottable.txt");
+ ShowStatus(tmp_output);
+
+ return 0;
+}
+
+/*==========================================
+ *
+ *------------------------------------------
+ */
+static int itemdb_read_itemslotcounttable(void)
+{
+ char *buf,*p;
+ int s;
+
+ buf=(char *) grfio_read("data\\itemslotcounttable.txt");
+ if(buf==NULL)
+ return -1;
+ s=grfio_size("data\\itemslotcounttable.txt");
+ buf[s]=0;
+ for(p=buf;p-buf<s;){
+ int nameid,slot;
+ sscanf(p,"%d#%d#",&nameid,&slot);
+ itemdb_search(nameid)->slot=slot;
+ p=strchr(p,10);
+ if(!p) break;
+ p++;
+ p=strchr(p,10);
+ if(!p) break;
+ p++;
+ }
+ aFree(buf);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","data\\itemslotcounttable.txt");
+ ShowStatus(tmp_output);
return 0;
}
-#endif /* TXT_ONLY */
+
/*==========================================
* ‘•”õ§ŒÀƒtƒ@ƒCƒ‹“Ç‚Ýo‚µ
*------------------------------------------
@@ -627,9 +705,47 @@ static int itemdb_read_noequip(void)
}
fclose(fp);
- printf("read db/item_noequip.txt done (count=%d)\n",ln);
+ if (ln > 0) {
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"db/item_noequip.txt");
+ ShowStatus(tmp_output);
+ }
return 0;
}
+
+/*================================================
+ * Whether the item can be refined or not [Celest]
+ *------------------------------------------------
+ */
+static int itemdb_read_norefine(void)
+{
+ int i, nameid;
+ struct item_data *id;
+ // To-do: let it read from a text file later
+ int cant_refine[] = {
+ 1243, 1530, 2110, 2112, 2201, 2202, 2203, 2204, 2205, 2210,
+ 2212, 2218, 2219, 2237, 2238, 2239, 2240, 2241, 2242, 2243,
+ 2250, 2253, 2260, 2262, 2263, 2264, 2265, 2266, 2267, 2268,
+ 2269, 2270, 2271, 2276, 2278, 2279, 2281, 2282, 2286, 2288,
+ 2289, 2290, 2291, 2292, 2293, 2295, 2296, 2297, 2298, 2352,
+ 2410, 2413, 2414, 2509, 2510, 2601, 2602, 2603, 2604, 2605,
+ 2607, 2608, 2609, 2610, 2611, 2612, 2613, 2614, 2615, 2616,
+ 2617, 2618, 2619, 2620, 2621, 2622, 2623, 2624, 2625, 2626,
+ 2627, 2628, 2629, 2630, 2631, 2634, 2635, 2636, 2637, 2638,
+ 2639, 2640, 5004, 5005, 5006, 5008, 5014, 5015, 5037, 5039,
+ 5040, 5043, 5046, 5049, 5050, 5051, 5053, 5054, 5055, 5058,
+ 5068, 5074, 5085, 5086, 5087, 5088, 5089, 5090, 5096, 5098, 0
+ };
+
+ for (i=0; i < (int)(sizeof(cant_refine) / sizeof(cant_refine[0])); i++) {
+ nameid = cant_refine[i];
+ if(nameid<=0 || nameid>=20000 || !(id=itemdb_exists(nameid)))
+ continue;
+ id->flag.no_refine = 1;
+ }
+
+ return 1;
+}
+
#ifndef TXT_ONLY
/*======================================
@@ -673,7 +789,7 @@ static int itemdb_read_sqldb(void)
// Insert a new row into the item database
- /*id = calloc(sizeof(struct item_data), 1);
+ /*id = aCalloc(sizeof(struct item_data), 1);
if (id == NULL)
{
@@ -723,7 +839,7 @@ static int itemdb_read_sqldb(void)
id->def = (sql_row[8] != NULL) ? atoi(sql_row[8]) : 0;
id->range = (sql_row[9] != NULL) ? atoi(sql_row[9]) : 0;
id->slot = (sql_row[10] != NULL) ? atoi(sql_row[10]) : 0;
- id->class = (sql_row[11] != NULL) ? atoi(sql_row[11]) : 0;
+ id->class_ = (sql_row[11] != NULL) ? atoi(sql_row[11]) : 0;
id->sex = (sql_row[12] != NULL) ? atoi(sql_row[12]) : 0;
id->equip = (sql_row[13] != NULL) ? atoi(sql_row[13]) : 0;
id->wlv = (sql_row[14] != NULL) ? atoi(sql_row[14]) : 0;
@@ -737,10 +853,10 @@ static int itemdb_read_sqldb(void)
if (sql_row[17] != NULL)
{
if (sql_row[17][0] == '{')
- id->use_script = parse_script(sql_row[17], 0);
+ id->use_script = parse_script((unsigned char *) sql_row[17], 0);
else {
sprintf(script, "{%s}", sql_row[17]);
- id->use_script = parse_script(script, 0);
+ id->use_script = parse_script((unsigned char *) script, 0);
}
}
else
@@ -751,10 +867,10 @@ static int itemdb_read_sqldb(void)
if (sql_row[18] != NULL)
{
if (sql_row[18][0] == '{')
- id->equip_script = parse_script(sql_row[18], 0);
+ id->equip_script = parse_script((unsigned char *) sql_row[18], 0);
else {
sprintf(script, "{%s}", sql_row[18]);
- id->equip_script = parse_script(script, 0);
+ id->equip_script = parse_script((unsigned char *) script, 0);
}
}
else
@@ -774,8 +890,8 @@ static int itemdb_read_sqldb(void)
{
printf("Database server error (retrieving rows from %s): %s\n", item_db_db, mysql_error(&mmysql_handle));
}
-
- printf("read %s done (count = %lu)\n", item_db_db, (unsigned long) mysql_num_rows(sql_res));
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",(unsigned long) mysql_num_rows(sql_res),item_db_db);
+ ShowStatus(tmp_output);
}
else
{
@@ -802,26 +918,20 @@ static int itemdb_final(void *key,void *data,va_list ap)
{
struct item_data *id;
- nullpo_retr(0, id=data);
+ nullpo_retr(0, id= (struct item_data *) data);
if(id->use_script)
- free(id->use_script);
+ aFree(id->use_script);
if(id->equip_script)
- free(id->equip_script);
- free(id);
+ aFree(id->equip_script);
+ aFree(id);
return 0;
}
void itemdb_reload(void)
{
- /*
-
- <empty item databases>
- itemdb_read();
-
- */
-
+ numdb_final(item_db,itemdb_final);
do_init_itemdb();
}
@@ -851,23 +961,6 @@ void itemdebugtxt()
fclose(dfp);
}
*/
-#ifdef TXT_ONLY
-/*====================================
- * Removed item_value_db, don't re-add
- *------------------------------------
- */
-static void itemdb_read(void)
-{
- itemdb_read_itemslottable();
- itemdb_readdb();
- itemdb_read_randomitem();
- itemdb_read_itemavail();
- itemdb_read_noequip();
- itemdb_read_cardillustnametable();
- if (!battle_config.item_name_override_grffile)
- itemdb_read_itemnametable();
-}
-#endif /* TXT_ONLY */
/*==========================================
*
*------------------------------------------
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index 0edfad243..2ba6ae7f6 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -12,7 +12,7 @@ struct item_data {
int value_buy;
int value_sell;
int type;
- int class;
+ int class_;
int sex;
int equip;
int weight;
@@ -33,6 +33,7 @@ struct item_data {
unsigned no_equip : 3;
unsigned no_drop : 1;
unsigned no_use : 1;
+ unsigned no_refine : 1; // [celest]
} flag;
int view_id;
};
diff --git a/src/map/log.c b/src/map/log.c
index 86c5a41a2..7cf4dfcf4 100644
--- a/src/map/log.c
+++ b/src/map/log.c
@@ -3,69 +3,117 @@
#include <stdio.h>
#include <string.h>
+#include "../common/strlib.h"
+#include "../common/nullpo.h"
+#include "itemdb.h"
#include "map.h"
-#include "nullpo.h"
#include "log.h"
struct Log_Config log_config;
+char timestring[255];
+time_t curtime;
+
+//FILTER OPTIONS
+//0 = Don't log
+//1 = Log any item
+//Bits: ||
+//2 - Healing items (0)
+//3 - Etc Items(3) + Arrows (10)
+//4 - Usable Items(2)
+//5 - Weapon(4)
+//6 - Shields,Armor,Headgears,Accessories,etc(5)
+//7 - Cards(6)
+//8 - Pet Accessories(8) + Eggs(7) (well, monsters don't drop 'em but we'll use the same system for ALL logs)
+//9 - Log expensive items ( >= price_log)
+//10 - Log big amount of items ( >= amount_log)
+//11 - Log refined items (if their refine >= refine_log )
+//12 - Log rare items (if their drop chance <= rare_log )
+
+//check if this item should be logger according the settings
+int should_log_item(int filter, int nameid) {
+ struct item_data *item_data;
+ if (nameid<512 || (item_data= itemdb_search(nameid)) == NULL) return 0;
+ if ( (filter&1) || // Filter = 1, we log any item
+ (filter&2 && item_data->type == 0 ) || //healing items
+ (filter&4 && (item_data->type == 3 || item_data->type == 10) ) || //etc+arrows
+ (filter&8 && item_data->type == 2 ) || //usable
+ (filter&16 && item_data->type == 4 ) || //weapon
+ (filter&32 && item_data->type == 5 ) || //armor
+ (filter&64 && item_data->type == 6 ) || //cards
+ (filter&128 && (item_data->type == 7 || item_data->type == 8) ) || //eggs+pet access
+ (filter&256 && item_data->value_buy >= log_config.price_items_log ) ||
+ (filter&512 && item_data->refine >= log_config.refine_items_log )
+ ) return item_data->nameid;
+
+ return 0;
+}
+
int log_branch(struct map_session_data *sd)
{
+#ifndef TXT_ONLY
+ char t_name[100];
+#endif
FILE *logfp;
if(log_config.enable_logs <= 0)
return 0;
nullpo_retr(0, sd);
- #ifndef TXT_ONLY
+#ifndef TXT_ONLY
if(log_config.sql_logs > 0)
{
- sprintf(tmp_sql, "INSERT INTO `%s` (`branch_date`, `account_id`, `char_id`, `char_name`, `map`) VALUES (NOW(), '%d', '%d', '%s', '%s')", log_config.log_branch_db, sd->status.account_id, sd->status.char_id, sd->status.name, sd->mapname);
+ sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`branch_date`, `account_id`, `char_id`, `char_name`, `map`) VALUES (NOW(), '%d', '%d', '%s', '%s')",
+ log_config.log_branch_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), sd->mapname);
if(mysql_query(&mmysql_handle, tmp_sql))
printf("DB server Error - %s\n",mysql_error(&mmysql_handle));
} else {
- #endif
- if((logfp=fopen(log_config.log_drop,"a+")) != NULL) {
- char timestring[255];
- time_t curtime;
+#endif
+ if((logfp=fopen(log_config.log_branch,"a+")) != NULL) {
time(&curtime);
strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
fprintf(logfp,"%s - %s[%d:%d]\t%s%s", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, sd->mapname, RETCODE);
fclose(logfp);
}
- #ifndef TXT_ONLY
+#ifndef TXT_ONLY
}
- #endif
+#endif
return 0;
}
int log_drop(struct map_session_data *sd, int monster_id, int *log_drop)
{
FILE *logfp;
+ int i,flag = 0;
if(log_config.enable_logs <= 0)
return 0;
nullpo_retr(0, sd);
- #ifndef TXT_ONLY
+ for (i = 0; i<10; i++) { //Should we log these items? [Lupus]
+ flag += should_log_item(log_config.drop,log_drop[i]);
+ }
+ if (flag==0) return 0; //we skip logging this items set - they doesn't met our logging conditions [Lupus]
+
+#ifndef TXT_ONLY
if(log_config.sql_logs > 0)
{
- sprintf(tmp_sql, "INSERT INTO `%s` (`drop_date`, `kill_char_id`, `monster_id`, `item1`, `item2`, `item3`, `item4`, `item5`, `item6`, `item7`, `item8`, `map`) VALUES (NOW(), '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s') ", log_config.log_drop_db, sd->status.char_id, monster_id, log_drop[0], log_drop[1], log_drop[2], log_drop[3], log_drop[4], log_drop[5], log_drop[6], log_drop[7], sd->mapname);
+ sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`drop_date`, `kill_char_id`, `monster_id`, `item1`, `item2`, `item3`, `item4`, `item5`, `item6`, `item7`, `item8`, `item9`, `itemCard`, `map`) VALUES (NOW(), '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s') ", log_config.log_drop_db, sd->status.char_id, monster_id, log_drop[0], log_drop[1], log_drop[2], log_drop[3], log_drop[4], log_drop[5], log_drop[6], log_drop[7], log_drop[8], log_drop[9], sd->mapname);
if(mysql_query(&mmysql_handle, tmp_sql))
printf("DB server Error - %s\n",mysql_error(&mmysql_handle));
} else {
- #endif
+#endif
if((logfp=fopen(log_config.log_drop,"a+")) != NULL) {
- char timestring[255];
+
time_t curtime;
time(&curtime);
strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
- fprintf(logfp,"%s - %s[%d:%d]\t%d\t%d,%d,%d,%d,%d,%d,%d,%d%s", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, monster_id, log_drop[0], log_drop[1], log_drop[2], log_drop[3], log_drop[4], log_drop[5], log_drop[6], log_drop[7], RETCODE);
+ fprintf(logfp,"%s - %s[%d:%d]\t%d\t%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%s", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, monster_id, log_drop[0], log_drop[1], log_drop[2], log_drop[3], log_drop[4], log_drop[5], log_drop[6], log_drop[7], log_drop[8], log_drop[9], RETCODE);
fclose(logfp);
}
- #ifndef TXT_ONLY
+#ifndef TXT_ONLY
}
- #endif
- return 0;
+#endif
+ return 1; //Logged
}
int log_mvpdrop(struct map_session_data *sd, int monster_id, int *log_mvp)
@@ -75,81 +123,87 @@ int log_mvpdrop(struct map_session_data *sd, int monster_id, int *log_mvp)
if(log_config.enable_logs <= 0)
return 0;
nullpo_retr(0, sd);
- #ifndef TXT_ONLY
+#ifndef TXT_ONLY
if(log_config.sql_logs > 0)
{
- sprintf(tmp_sql, "INSERT INTO `%s` (`mvp_date`, `kill_char_id`, `monster_id`, `prize`, `mvpexp`, `map`) VALUES (NOW(), '%d', '%d', '%d', '%d', '%s') ", log_config.log_mvpdrop_db, sd->status.char_id, monster_id, log_mvp[0], log_mvp[1], sd->mapname);
+ sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`mvp_date`, `kill_char_id`, `monster_id`, `prize`, `mvpexp`, `map`) VALUES (NOW(), '%d', '%d', '%d', '%d', '%s') ", log_config.log_mvpdrop_db, sd->status.char_id, monster_id, log_mvp[0], log_mvp[1], sd->mapname);
if(mysql_query(&mmysql_handle, tmp_sql))
printf("DB server Error - %s\n",mysql_error(&mmysql_handle));
} else {
- #endif
+#endif
if((logfp=fopen(log_config.log_mvpdrop,"a+")) != NULL) {
- char timestring[255];
- time_t curtime;
time(&curtime);
strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
fprintf(logfp,"%s - %s[%d:%d]\t%d\t%d,%d%s", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, monster_id, log_mvp[0], log_mvp[1], RETCODE);
fclose(logfp);
}
- #ifndef TXT_ONLY
+#ifndef TXT_ONLY
}
- #endif
+#endif
return 0;
}
int log_present(struct map_session_data *sd, int source_type, int nameid)
{
FILE *logfp;
+#ifndef TXT_ONLY
+ char t_name[100];
+#endif
+
if(log_config.enable_logs <= 0)
return 0;
nullpo_retr(0, sd);
- #ifndef TXT_ONLY
+ if(!should_log_item(log_config.present,nameid)) return 0; //filter [Lupus]
+#ifndef TXT_ONLY
if(log_config.sql_logs > 0)
{
- sprintf(tmp_sql, "INSERT INTO `%s` (`present_date`, `src_id`, `account_id`, `char_id`, `char_name`, `nameid`, `map`) VALUES (NOW(), '%d', '%d', '%d', '%s', '%d', '%s') ", log_config.log_present_db, source_type, sd->status.account_id, sd->status.char_id, sd->status.name, nameid, sd->mapname);
+ sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`present_date`, `src_id`, `account_id`, `char_id`, `char_name`, `nameid`, `map`) VALUES (NOW(), '%d', '%d', '%d', '%s', '%d', '%s') ",
+ log_config.log_present_db, source_type, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), nameid, sd->mapname);
if(mysql_query(&mmysql_handle, tmp_sql))
printf("DB server Error - %s\n",mysql_error(&mmysql_handle));
} else {
- #endif
+#endif
if((logfp=fopen(log_config.log_present,"a+")) != NULL) {
- char timestring[255];
- time_t curtime;
time(&curtime);
strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
fprintf(logfp,"%s - %s[%d:%d]\t%d\t%d%s", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, source_type, nameid, RETCODE);
fclose(logfp);
}
- #ifndef TXT_ONLY
+#ifndef TXT_ONLY
}
- #endif
+#endif
return 0;
}
int log_produce(struct map_session_data *sd, int nameid, int slot1, int slot2, int slot3, int success)
{
FILE *logfp;
+#ifndef TXT_ONLY
+ char t_name[100];
+#endif
+
if(log_config.enable_logs <= 0)
return 0;
nullpo_retr(0, sd);
- #ifndef TXT_ONLY
+ if(!should_log_item(log_config.produce,nameid)) return 0; //filter [Lupus]
+#ifndef TXT_ONLY
if(log_config.sql_logs > 0)
{
- sprintf(tmp_sql, "INSERT INTO `%s` (`produce_date`, `account_id`, `char_id`, `char_name`, `nameid`, `slot1`, `slot2`, `slot3`, `map`, `success`) VALUES (NOW(), '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%s', '%d') ", log_config.log_produce_db, sd->status.account_id, sd->status.char_id, sd->status.name, nameid, slot1, slot2, slot3, sd->mapname, success);
+ sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`produce_date`, `account_id`, `char_id`, `char_name`, `nameid`, `slot1`, `slot2`, `slot3`, `map`, `success`) VALUES (NOW(), '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%s', '%d') ",
+ log_config.log_produce_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), nameid, slot1, slot2, slot3, sd->mapname, success);
if(mysql_query(&mmysql_handle, tmp_sql))
printf("DB server Error - %s\n",mysql_error(&mmysql_handle));
} else {
- #endif
+#endif
if((logfp=fopen(log_config.log_produce,"a+")) != NULL) {
- char timestring[255];
- time_t curtime;
time(&curtime);
strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
fprintf(logfp,"%s - %s[%d:%d]\t%d\t%d,%d,%d\t%d%s", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, nameid, slot1, slot2, slot3, success, RETCODE);
fclose(logfp);
}
- #ifndef TXT_ONLY
+#ifndef TXT_ONLY
}
- #endif
+#endif
return 0;
}
@@ -159,6 +213,9 @@ int log_refine(struct map_session_data *sd, int n, int success)
int log_card[4];
int item_level;
int i;
+#ifndef TXT_ONLY
+ char t_name[100];
+#endif
if(log_config.enable_logs <= 0)
return 0;
@@ -169,37 +226,100 @@ int log_refine(struct map_session_data *sd, int n, int success)
item_level = 0;
else
item_level = sd->status.inventory[n].refine + 1;
-
+ if(!should_log_item(log_config.refine,sd->status.inventory[n].nameid)) return 0; //filter [Lupus]
for(i=0;i<4;i++)
log_card[i] = sd->status.inventory[n].card[i];
- #ifndef TXT_ONLY
+#ifndef TXT_ONLY
if(log_config.sql_logs > 0)
{
- sprintf(tmp_sql, "INSERT INTO `%s` (`refine_date`, `account_id`, `char_id`, `char_name`, `nameid`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`, `success`, `item_level`) VALUES (NOW(), '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%s', '%d', '%d')", log_config.log_refine_db, sd->status.account_id, sd->status.char_id, sd->status.name, sd->status.inventory[n].nameid, sd->status.inventory[n].refine, log_card[0], log_card[1], log_card[2], log_card[3], sd->mapname, success, item_level);
+ sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`refine_date`, `account_id`, `char_id`, `char_name`, `nameid`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`, `success`, `item_level`) VALUES (NOW(), '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%s', '%d', '%d')",
+ log_config.log_refine_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), sd->status.inventory[n].nameid, sd->status.inventory[n].refine, log_card[0], log_card[1], log_card[2], log_card[3], sd->mapname, success, item_level);
if(mysql_query(&mmysql_handle, tmp_sql))
printf("DB server Error - %s\n",mysql_error(&mmysql_handle));
} else {
- #endif
+#endif
if((logfp=fopen(log_config.log_refine,"a+")) != NULL) {
- char timestring[255];
- time_t curtime;
time(&curtime);
strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
fprintf(logfp,"%s - %s[%d:%d]\t%d,%d\t%d%d%d%d\t%d,%d%s", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, sd->status.inventory[n].nameid, sd->status.inventory[n].refine, log_card[0], log_card[1], log_card[2], log_card[3], success, item_level, RETCODE);
fclose(logfp);
}
- #ifndef TXT_ONLY
+#ifndef TXT_ONLY
}
- #endif
+#endif
return 0;
}
+int log_tostorage(struct map_session_data *sd,int n, int guild)
+{
+ FILE *logfp;
+
+ if(log_config.enable_logs <= 0 || log_config.storage == 0 || log_config.log_storage[0] == '\0')
+ return 0;
+
+ nullpo_retr(0, sd);
+ if(sd->status.inventory[n].nameid==0 || sd->inventory_data[n] == NULL)
+ return 1;
+
+ if(sd->status.inventory[n].amount < 0)
+ return 1;
+
+ if((logfp=fopen(log_config.log_trade,"a+")) != NULL) {
+ time(&curtime);
+ strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+ fprintf(logfp,"%s - to %s: %s[%d:%d]\t%d\t%d\t%d\t%d,%d,%d,%d%s", timestring, guild ? "guild_storage": "storage", sd->status.name, sd->status.account_id, sd->status.char_id,
+ sd->status.inventory[n].nameid,
+ sd->status.inventory[n].amount,
+ sd->status.inventory[n].refine,
+ sd->status.inventory[n].card[0],
+ sd->status.inventory[n].card[1],
+ sd->status.inventory[n].card[2],
+ sd->status.inventory[n].card[3], RETCODE);
+ fclose(logfp);
+ }
+ return 0;
+}
+
+int log_fromstorage(struct map_session_data *sd,int n, int guild)
+{
+ FILE *logfp;
+
+ if(log_config.enable_logs <= 0 || log_config.storage == 0 || log_config.log_storage[0] == '\0')
+ return 0;
+
+ nullpo_retr(0, sd);
+
+ if(sd->status.inventory[n].nameid==0 || sd->inventory_data[n] == NULL)
+ return 1;
+
+ if(sd->status.inventory[n].amount < 0)
+ return 1;
+
+ if((logfp=fopen(log_config.log_trade,"a+")) != NULL) {
+ time(&curtime);
+ strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+ fprintf(logfp,"%s - from %s: %s[%d:%d]\t%d\t%d\t%d\t%d,%d,%d,%d%s", timestring, guild ? "guild_storage": "storage", sd->status.name, sd->status.account_id, sd->status.char_id,
+ sd->status.inventory[n].nameid,
+ sd->status.inventory[n].amount,
+ sd->status.inventory[n].refine,
+ sd->status.inventory[n].card[0],
+ sd->status.inventory[n].card[1],
+ sd->status.inventory[n].card[2],
+ sd->status.inventory[n].card[3], RETCODE);
+ fclose(logfp);
+ }
+ return 0;
+}
+
int log_trade(struct map_session_data *sd, struct map_session_data *target_sd, int n,int amount)
{
FILE *logfp;
int log_nameid, log_amount, log_refine, log_card[4];
int i;
+#ifndef TXT_ONLY
+ char t_name[100],t_name2[100];
+#endif
if(log_config.enable_logs <= 0)
return 0;
@@ -211,7 +331,7 @@ int log_trade(struct map_session_data *sd, struct map_session_data *target_sd, i
if(sd->status.inventory[n].amount < 0)
return 1;
-
+ if(!should_log_item(log_config.trade,sd->status.inventory[n].nameid)) return 0; //filter [Lupus]
log_nameid = sd->status.inventory[n].nameid;
log_amount = sd->status.inventory[n].amount;
log_refine = sd->status.inventory[n].refine;
@@ -219,25 +339,24 @@ int log_trade(struct map_session_data *sd, struct map_session_data *target_sd, i
for(i=0;i<4;i++)
log_card[i] = sd->status.inventory[n].card[i];
- #ifndef TXT_ONLY
+#ifndef TXT_ONLY
if(log_config.sql_logs > 0)
{
- sprintf(tmp_sql, "INSERT INTO `%s` (`trade_date`, `src_account_id`, `src_char_id`, `src_char_name`, `des_account_id`, `des_char_id`, `des_char_name`, `nameid`, `amount`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`) VALUES (NOW(), '%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s')", log_config.log_trade_db, sd->status.account_id, sd->status.char_id, sd->status.name, target_sd->status.account_id, target_sd->status.char_id, target_sd->status.name, log_nameid, log_amount, log_refine, log_card[0], log_card[1], log_card[2], log_card[3], sd->mapname);
+ sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`trade_date`, `src_account_id`, `src_char_id`, `src_char_name`, `des_account_id`, `des_char_id`, `des_char_name`, `nameid`, `amount`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`) VALUES (NOW(), '%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s')",
+ log_config.log_trade_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), target_sd->status.account_id, target_sd->status.char_id, jstrescapecpy(t_name2, target_sd->status.name), log_nameid, log_amount, log_refine, log_card[0], log_card[1], log_card[2], log_card[3], sd->mapname);
if(mysql_query(&mmysql_handle, tmp_sql))
printf("DB server Error - %s\n",mysql_error(&mmysql_handle));
} else {
- #endif
+#endif
if((logfp=fopen(log_config.log_trade,"a+")) != NULL) {
- char timestring[255];
- time_t curtime;
time(&curtime);
strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
fprintf(logfp,"%s - %s[%d:%d]\t%s[%d:%d]\t%d\t%d\t%d\t%d,%d,%d,%d%s", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, target_sd->status.name, target_sd->status.account_id, target_sd->status.char_id, log_nameid, log_amount, log_refine, log_card[0], log_card[1], log_card[2], log_card[3], RETCODE);
fclose(logfp);
}
- #ifndef TXT_ONLY
+#ifndef TXT_ONLY
}
- #endif
+#endif
return 0;
}
@@ -246,6 +365,9 @@ int log_vend(struct map_session_data *sd,struct map_session_data *vsd,int n,int
FILE *logfp;
int log_nameid, log_amount, log_refine, log_card[4];
int i;
+#ifndef TXT_ONLY
+ char t_name[100],t_name2[100];
+#endif
if(log_config.enable_logs <= 0)
return 0;
@@ -255,88 +377,124 @@ int log_vend(struct map_session_data *sd,struct map_session_data *vsd,int n,int
return 1;
if(sd->status.inventory[n].amount< 0)
return 1;
-
+ if(!should_log_item(log_config.vend,sd->status.inventory[n].nameid)) return 0; //filter [Lupus]
log_nameid = sd->status.inventory[n].nameid;
log_amount = sd->status.inventory[n].amount;
log_refine = sd->status.inventory[n].refine;
for(i=0;i<4;i++)
log_card[i] = sd->status.inventory[n].card[i];
- #ifndef TXT_ONLY
+#ifndef TXT_ONLY
if(log_config.sql_logs > 0)
{
- sprintf(tmp_sql, "INSERT INTO `%s` (`vend_date`, `vend_account_id`, `vend_char_id`, `vend_char_name`, `buy_account_id`, `buy_char_id`, `buy_char_name`, `nameid`, `amount`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`, `zeny`) VALUES (NOW(), '%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s', '%d')", log_config.log_vend_db, sd->status.account_id, sd->status.char_id, sd->status.name, vsd->status.account_id, vsd->status.char_id, vsd->status.name, log_nameid, log_amount, log_refine, log_card[0], log_card[1], log_card[2], log_card[3], sd->mapname, zeny);
+ sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`vend_date`, `vend_account_id`, `vend_char_id`, `vend_char_name`, `buy_account_id`, `buy_char_id`, `buy_char_name`, `nameid`, `amount`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`, `zeny`) VALUES (NOW(), '%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s', '%d')",
+ log_config.log_vend_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), vsd->status.account_id, vsd->status.char_id, jstrescapecpy(t_name2, vsd->status.name), log_nameid, log_amount, log_refine, log_card[0], log_card[1], log_card[2], log_card[3], sd->mapname, zeny);
if(mysql_query(&mmysql_handle, tmp_sql))
printf("DB server Error - %s\n",mysql_error(&mmysql_handle));
} else {
- #endif
+#endif
if((logfp=fopen(log_config.log_vend,"a+")) != NULL) {
- char timestring[255];
- time_t curtime;
time(&curtime);
strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
fprintf(logfp,"%s - %s[%d:%d]\t%s[%d:%d]\t%d\t%d\t%d\t%d,%d,%d,%d\t%d%s", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, vsd->status.name, vsd->status.account_id, vsd->status.char_id, log_nameid, log_amount, log_refine, log_card[0], log_card[1], log_card[2], log_card[3], zeny, RETCODE);
fclose(logfp);
}
- #ifndef TXT_ONLY
+#ifndef TXT_ONLY
}
- #endif
+#endif
return 0;
}
int log_zeny(struct map_session_data *sd, struct map_session_data *target_sd,int amount)
{
FILE *logfp;
+#ifndef TXT_ONLY
+ char t_name[100],t_name2[100];
+#endif
+
if(log_config.enable_logs <= 0)
return 0;
nullpo_retr(0, sd);
- #ifndef TXT_ONLY
+#ifndef TXT_ONLY
if(log_config.sql_logs > 0)
{
- sprintf(tmp_sql,"INSERT INTO `%s` (`trade_date`, `src_account_id`, `src_char_id`, `src_char_name`, `des_account_id`, `des_char_id`, `des_char_name`, `map`, `zeny`) VALUES (NOW(), '%d', '%d', '%s', '%d', '%d', '%s', '%s', '%d')", log_config.log_trade_db, sd->status.account_id, sd->status.char_id, sd->status.name, target_sd->status.account_id, target_sd->status.char_id, target_sd->status.name, sd->mapname, sd->deal_zeny);
+ sprintf(tmp_sql,"INSERT DELAYED INTO `%s` (`trade_date`, `src_account_id`, `src_char_id`, `src_char_name`, `des_account_id`, `des_char_id`, `des_char_name`, `map`, `zeny`) VALUES (NOW(), '%d', '%d', '%s', '%d', '%d', '%s', '%s', '%d')",
+ log_config.log_trade_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), target_sd->status.account_id, target_sd->status.char_id, jstrescapecpy(t_name2, target_sd->status.name), sd->mapname, sd->deal_zeny);
if(mysql_query(&mmysql_handle, tmp_sql))
printf("DB server Error - %s\n",mysql_error(&mmysql_handle));
} else {
- #endif
+#endif
if((logfp=fopen(log_config.log_trade,"a+")) != NULL) {
- char timestring[255];
- time_t curtime;
time(&curtime);
strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
fprintf(logfp,"%s - %s[%d]\t%s[%d]\t%d\t%s", timestring, sd->status.name, sd->status.account_id, target_sd->status.name, target_sd->status.account_id, sd->deal_zeny, RETCODE);
fclose(logfp);
}
- #ifndef TXT_ONLY
+#ifndef TXT_ONLY
}
- #endif
+#endif
return 0;
}
int log_atcommand(struct map_session_data *sd, const char *message)
{
FILE *logfp;
+#ifndef TXT_ONLY
+ char t_name[100];
+#endif
+
if(log_config.enable_logs <= 0)
return 0;
nullpo_retr(0, sd);
- #ifndef TXT_ONLY
+#ifndef TXT_ONLY
if(log_config.sql_logs > 0)
{
- sprintf(tmp_sql, "INSERT INTO `%s` (`atcommand_date`, `account_id`, `char_id`, `char_name`, `map`, `command`) VALUES(NOW(), '%d', '%d', '%s', '%s', '%s') ", log_config.log_gm_db, sd->status.account_id, sd->status.char_id, sd->status.name, sd->mapname, message);
+ sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`atcommand_date`, `account_id`, `char_id`, `char_name`, `map`, `command`) VALUES(NOW(), '%d', '%d', '%s', '%s', '%s') ",
+ log_config.log_gm_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), sd->mapname, message);
if(mysql_query(&mmysql_handle, tmp_sql))
printf("DB server Error - %s\n",mysql_error(&mmysql_handle));
} else {
- #endif
+#endif
if((logfp=fopen(log_config.log_gm,"a+")) != NULL) {
- char timestring[255];
- time_t curtime;
time(&curtime);
strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
fprintf(logfp,"%s - %s[%d]: %s%s",timestring,sd->status.name,sd->status.account_id,message,RETCODE);
fclose(logfp);
}
- #ifndef TXT_ONLY
+#ifndef TXT_ONLY
}
+#endif
+ return 0;
+}
+
+int log_npc(struct map_session_data *sd, const char *message)
+{ //[Lupus]
+ FILE *logfp;
+ #ifndef TXT_ONLY
+ char t_name[100];
#endif
+
+ if(log_config.enable_logs <= 0)
+ return 0;
+ nullpo_retr(0, sd);
+#ifndef TXT_ONLY
+ if(log_config.sql_logs > 0)
+ {
+ sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`npc_date`, `account_id`, `char_id`, `char_name`, `map`, `mes`) VALUES(NOW(), '%d', '%d', '%s', '%s', '%s') ",
+ log_config.log_npc_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), sd->mapname, message);
+ if(mysql_query(&mmysql_handle, tmp_sql))
+ printf("DB server Error - %s\n",mysql_error(&mmysql_handle));
+ } else {
+#endif
+ if((logfp=fopen(log_config.log_npc,"a+")) != NULL) {
+ time(&curtime);
+ strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+ fprintf(logfp,"%s - %s[%d]: %s%s",timestring,sd->status.name,sd->status.account_id,message,RETCODE);
+ fclose(logfp);
+ }
+#ifndef TXT_ONLY
+ }
+#endif
return 0;
}
@@ -345,11 +503,19 @@ int log_config_read(char *cfgName)
char line[1024], w1[1024], w2[1024];
FILE *fp;
+ memset(&log_config, 0, sizeof(log_config));
+
if((fp = fopen(cfgName, "r")) == NULL)
{
printf("Log configuration file not found at: %s\n", cfgName);
return 1;
}
+
+ //LOG FILTER Default values
+ log_config.refine_items_log = 7; //log refined items, with refine >= +7
+ log_config.rare_items_log = 100; //log rare items. drop chance <= 1%
+ log_config.price_items_log = 1000; //1000z
+ log_config.amount_items_log = 100;
while(fgets(line, sizeof(line) -1, fp))
{
@@ -362,6 +528,16 @@ int log_config_read(char *cfgName)
log_config.enable_logs = (atoi(w2));
} else if(strcmpi(w1,"sql_logs") == 0) {
log_config.sql_logs = (atoi(w2));
+//start of common filter settings
+ } else if(strcmpi(w1,"rare_items_log") == 0) {
+ log_config.rare_items_log = (atoi(w2));
+ } else if(strcmpi(w1,"refine_items_log") == 0) {
+ log_config.refine_items_log = (atoi(w2));
+ } else if(strcmpi(w1,"price_items_log") == 0) {
+ log_config.price_items_log = (atoi(w2));
+ } else if(strcmpi(w1,"amount_items_log") == 0) {
+ log_config.amount_items_log = (atoi(w2));
+//end of common filter settings
} else if(strcmpi(w1,"log_branch") == 0) {
log_config.branch = (atoi(w2));
} else if(strcmpi(w1,"log_drop") == 0) {
@@ -376,6 +552,8 @@ int log_config_read(char *cfgName)
log_config.refine = (atoi(w2));
} else if(strcmpi(w1,"log_trade") == 0) {
log_config.trade = (atoi(w2));
+ } else if(strcmpi(w1,"log_storage") == 0) {
+ log_config.storage = (atoi(w2));
} else if(strcmpi(w1,"log_vend") == 0) {
log_config.vend = (atoi(w2));
} else if(strcmpi(w1,"log_zeny") == 0) {
@@ -383,10 +561,13 @@ int log_config_read(char *cfgName)
log_config.zeny = 0;
else
log_config.zeny = (atoi(w2));
- } else if(strcmpi(w1,"log_gm") == 0) {
+ } else if(strcmpi(w1,"log_gm") == 0) {
log_config.gm = (atoi(w2));
+ } else if(strcmpi(w1,"log_npc") == 0) {
+ log_config.npc = (atoi(w2));
}
+#ifndef TXT_ONLY
else if(strcmpi(w1, "log_branch_db") == 0) {
strcpy(log_config.log_branch_db, w2);
if(log_config.branch == 1)
@@ -420,6 +601,13 @@ int log_config_read(char *cfgName)
printf("and Zeny Trades");
printf(" to table `%s`\n", w2);
}
+// } else if(strcmpi(w1, "log_storage_db") == 0) {
+// strcpy(log_config.log_storage_db, w2);
+// if(log_config.storage == 1)
+// {
+// printf("Logging Item Storages");
+// printf(" to table `%s`\n", w2);
+// }
} else if(strcmpi(w1, "log_vend_db") == 0) {
strcpy(log_config.log_vend_db, w2);
if(log_config.vend == 1)
@@ -428,49 +616,68 @@ int log_config_read(char *cfgName)
strcpy(log_config.log_gm_db, w2);
if(log_config.gm > 0)
printf("Logging GM Level %d Commands to table `%s`\n", log_config.gm, w2);
+ } else if(strcmpi(w1, "log_npc_db") == 0) {
+ strcpy(log_config.log_npc_db, w2);
+ if(log_config.npc > 0)
+ printf("Logging NPC 'logmes' to table `%s`\n", w2);
}
+#endif
- else if(strcmpi(w1, "log_branch") == 0) {
+ else if(strcmpi(w1, "log_branch_file") == 0) {
strcpy(log_config.log_branch, w2);
- if(log_config.branch == 1)
+ if(log_config.branch > 0 && log_config.sql_logs < 1)
printf("Logging Dead Branch Usage to file `%s`.txt\n", w2);
- } else if(strcmpi(w1, "log_drop") == 0) {
+ } else if(strcmpi(w1, "log_drop_file") == 0) {
strcpy(log_config.log_drop, w2);
- if(log_config.drop == 1)
+ if(log_config.drop > 0 && log_config.sql_logs < 1)
printf("Logging Item Drops to file `%s`.txt\n", w2);
- } else if(strcmpi(w1, "log_mvpdrop") == 0) {
+ } else if(strcmpi(w1, "log_mvpdrop_file") == 0) {
strcpy(log_config.log_mvpdrop, w2);
- if(log_config.mvpdrop == 1)
+ if(log_config.mvpdrop > 0 && log_config.sql_logs < 1)
printf("Logging MVP Drops to file `%s`.txt\n", w2);
- } else if(strcmpi(w1, "log_present") == 0) {
+ } else if(strcmpi(w1, "log_present_file") == 0) {
strcpy(log_config.log_present, w2);
- if(log_config.present == 1)
+ if(log_config.present > 0 && log_config.sql_logs < 1)
printf("Logging Present Usage & Results to file `%s`.txt\n", w2);
- } else if(strcmpi(w1, "log_produce") == 0) {
+ } else if(strcmpi(w1, "log_produce_file") == 0) {
strcpy(log_config.log_produce, w2);
- if(log_config.produce == 1)
+ if(log_config.produce > 0 && log_config.sql_logs < 1)
printf("Logging Producing to file `%s`.txt\n", w2);
- } else if(strcmpi(w1, "log_refine") == 0) {
+ } else if(strcmpi(w1, "log_refine_file") == 0) {
strcpy(log_config.log_refine, w2);
- if(log_config.refine == 1)
+ if(log_config.refine > 0 && log_config.sql_logs < 1)
printf("Logging Refining to file `%s`.txt\n", w2);
- } else if(strcmpi(w1, "log_trade") == 0) {
+ } else if(strcmpi(w1, "log_trade_file") == 0) {
strcpy(log_config.log_trade, w2);
- if(log_config.trade == 1)
+ if(log_config.trade > 0 && log_config.sql_logs < 1)
{
printf("Logging Item Trades");
- if(log_config.zeny == 1)
+ if(log_config.zeny > 0)
printf("and Zeny Trades");
printf(" to file `%s`.txt\n", w2);
}
- } else if(strcmpi(w1, "log_vend") == 0) {
+ } else if(strcmpi(w1, "log_storage_file") == 0) {
+ strcpy(log_config.log_storage, w2);
+ if(log_config.storage > 0 && log_config.sql_logs < 1)
+ {
+ printf("Logging Item Storages");
+ printf(" to file `%s`.txt\n", w2);
+ }
+ } else if(strcmpi(w1, "log_vend_file") == 0) {
strcpy(log_config.log_vend, w2);
- if(log_config.vend == 1)
+ if(log_config.vend > 0 && log_config.sql_logs < 1)
printf("Logging Vending to file `%s`.txt\n", w2);
- } else if(strcmpi(w1, "log_gm") == 0) {
+ } else if(strcmpi(w1, "log_gm_file") == 0) {
strcpy(log_config.log_gm, w2);
- if(log_config.gm > 0)
+ if(log_config.gm > 0 && log_config.sql_logs < 1)
printf("Logging GM Level %d Commands to file `%s`.txt\n", log_config.gm, w2);
+ } else if(strcmpi(w1, "log_npc_file") == 0) {
+ strcpy(log_config.log_npc, w2);
+ if(log_config.npc > 0 && log_config.sql_logs < 1)
+ printf("Logging NPC 'logmes' to file `%s`.txt\n", w2);
+ //support the import command, just like any other config
+ } else if(strcmpi(w1,"import") == 0) {
+ log_config_read(w2);
}
}
}
diff --git a/src/map/log.h b/src/map/log.h
index d4ad0bd66..cdb543f0d 100644
--- a/src/map/log.h
+++ b/src/map/log.h
@@ -16,18 +16,25 @@ int log_present(struct map_session_data *sd, int source_type, int nameid);
int log_produce(struct map_session_data *sd, int nameid, int slot1, int slot2, int slot3, int success);
int log_refine(struct map_session_data *sd, int n, int success);
int log_trade(struct map_session_data *sd,struct map_session_data *target_sd,int n,int amount);
+int log_tostorage(struct map_session_data *sd,int n, int guild);
+int log_fromstorage(struct map_session_data *sd,int n, int guild);
+
int log_vend(struct map_session_data *sd,struct map_session_data *vsd,int n,int amount,int zeny);
int log_zeny(struct map_session_data *sd, struct map_session_data *target_sd,int amount);
int log_atcommand(struct map_session_data *sd, const char *message);
+int log_npc(struct map_session_data *sd, const char *message);
int log_config_read(char *cfgName);
extern struct Log_Config {
int enable_logs;
int sql_logs;
- int branch, drop, mvpdrop, present, produce, refine, trade, vend, zeny, gm;
- char log_branch[32], log_drop[32], log_mvpdrop[32], log_present[32], log_produce[32], log_refine[32], log_trade[32], log_vend[32], log_gm[32];
- char log_branch_db[32], log_drop_db[32], log_mvpdrop_db[32], log_present_db[32], log_produce_db[32], log_refine_db[32], log_trade_db[32], log_vend_db[32], log_gm_db[32];
+ int rare_items_log,refine_items_log,price_items_log,amount_items_log;
+ int branch, drop, mvpdrop, present, produce, refine, trade, vend, zeny, gm, npc, storage;
+ char log_branch[32], log_drop[32], log_mvpdrop[32], log_present[32], log_produce[32], log_refine[32], log_trade[32], log_vend[32], log_gm[32], log_npc[32], log_storage[32];
+ char log_branch_db[32], log_drop_db[32], log_mvpdrop_db[32], log_present_db[32], log_produce_db[32], log_refine_db[32], log_trade_db[32], log_vend_db[32], log_gm_db[32], log_npc_db[32];
+ int uptime;
+ char log_uptime[32];
} log_config;
#endif
diff --git a/src/map/mail.c b/src/map/mail.c
index 019f6303d..42a83de52 100644
--- a/src/map/mail.c
+++ b/src/map/mail.c
@@ -1,18 +1,22 @@
+#ifndef TXT_ONLY
// Mail System for eAthena SQL
// Created by Valaris
+// moved all strings to msg_athena.conf [Lupus]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "socket.h"
-#include "timer.h"
-#include "nullpo.h"
+#include "../common/strlib.h"
+#include "../common/socket.h"
+#include "../common/timer.h"
+#include "../common/nullpo.h"
#include "map.h"
#include "clif.h"
#include "chrif.h"
#include "intif.h"
+#include "atcommand.h"
#include "pc.h"
#include "mail.h"
@@ -20,6 +24,7 @@ char mail_db[32] = "mail";
int MAIL_CHECK_TIME = 120000;
int mail_timer;
+//extern char *msg_table[1000]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others)
#ifdef MEMWATCH
#include "memwatch.h"
@@ -27,13 +32,13 @@ int mail_timer;
int mail_check(struct map_session_data *sd,int type)
{
- int i=0,new=0,priority=0;
+ int i = 0, new_ = 0, priority = 0;
char message[50];
- if(sd==NULL)
- return 0;
-
- sprintf(tmp_msql,"SELECT `message_id`,`to_account_id`,`from_char_name`,`read_flag`,`priority`,`check_flag` FROM `%s` WHERE `to_account_id` = \"%d\" ORDER by `message_id`", mail_db, sd->status.account_id);
+ nullpo_retr (0, sd);
+
+ sprintf(tmp_msql,"SELECT `message_id`,`to_account_id`,`from_char_name`,`read_flag`,`priority`,`check_flag` "
+ "FROM `%s` WHERE `to_account_id` = \"%d\" ORDER by `message_id`", mail_db, sd->status.account_id);
if (mysql_query(&mail_handle, tmp_msql)) {
printf("Database server error (executing query for %s): %s\n", mail_db, mysql_error(&mail_handle));
@@ -42,63 +47,66 @@ int mail_check(struct map_session_data *sd,int type)
mail_res = mysql_store_result(&mail_handle);
if(mail_res) {
- if (mysql_num_rows(mail_res) == 0) {
- clif_displaymessage(sd->fd,"You have no messages.");
- mysql_free_result(mail_res);
- return 0;
- }
+ if (mysql_num_rows(mail_res) == 0) {
+ //clif_displaymessage(sd->fd,"You have no messages.");
+ clif_displaymessage(sd->fd, msg_txt(516));
- while ((mail_row = mysql_fetch_row(mail_res))) {
- i++;
+ mysql_free_result(mail_res);
+ return 0;
+ }
- if(!atoi(mail_row[5])) {
+ while ((mail_row = mysql_fetch_row(mail_res))) {
+ i++;
+ if(!atoi(mail_row[5])) {
sprintf(tmp_msql,"UPDATE `%s` SET `check_flag`='1' WHERE `message_id`= \"%d\"", mail_db, atoi(mail_row[0]));
- if(mysql_query(&mail_handle, tmp_msql) ) {
- printf("DB server Error (update Read `%s`)- %s\n", mail_db, mysql_error(&mail_handle) );
- }
+ if(mysql_query(&mail_handle, tmp_msql) ) {
+ printf("DB server Error (update Read `%s`)- %s\n", mail_db, mysql_error(&mail_handle) );
}
+ }
- if(!atoi(mail_row[3])) {
- new++;
- if(atoi(mail_row[4]))
- priority++;
- if(type==2 || type==3) {
- if(atoi(mail_row[4])) {
- sprintf(message, "%d - From : %s (New - Priority)", i, mail_row[2]);
- clif_displaymessage(sd->fd, message);
- }
-
- else {
- sprintf(message, "%d - From : %s (New)", i, mail_row[2]);
- clif_displaymessage(sd->fd, message);
- }
+ if(!atoi(mail_row[3])) {
+ new_++;
+ if(atoi(mail_row[4]))
+ priority++;
+ if(type==2 || type==3) {
+ if(atoi(mail_row[4])) {
+ //sprintf(message, "%d - From : %s (New - Priority)", i, mail_row[2]);
+ sprintf(message, msg_txt(511), i, mail_row[2]);
+
+ clif_displaymessage(sd->fd, jstrescape(message));
+ } else {
+ //sprintf(message, "%d - From : %s (New)", i, mail_row[2]);
+ sprintf(message, msg_txt(512), i, mail_row[2]);
+ clif_displaymessage(sd->fd, jstrescape(message));
}
}
+ } else if(type==2){
+ //sprintf(message, "%d - From : %s", i, mail_row[2]);
+ sprintf(message, msg_txt(513), i, mail_row[2]);
+ clif_displaymessage(sd->fd, jstrescape(message));
+ }
+ }
- else if(type==2){
- sprintf(message, "%d - From : %s", i, mail_row[2]);
- clif_displaymessage(sd->fd, message);
- }
-
- }
-
mysql_free_result(mail_res);
-
} else {
- printf("MySQL error (storing query result for %s): %s\n", mail_db, mysql_error(&mail_handle));
+ printf("MySQL error (storing query result for %s): %s\n", mail_db, mysql_error(&mail_handle));
return 0;
- }
+ }
- if(i>0 && new>0 && type==1) {
- sprintf(message, "You have %d new messages.", new);
- clif_displaymessage(sd->fd, message);
+ if(i>0 && new_>0 && type==1) {
+ //sprintf(message, "You have %d new messages.", new_);
+ sprintf(message, msg_txt(514), new_);
+
+ clif_displaymessage(sd->fd, jstrescape(message));
}
- if(i>0 && new>0 && priority>0 && type==1) {
- sprintf(message, "You have %d unread priority messages.", priority);
- clif_displaymessage(sd->fd, message);
+ if(i>0 && new_>0 && priority>0 && type==1) {
+ //sprintf(message, "You have %d unread priority messages.", priority);
+ sprintf(message, msg_txt(515), priority);
+ clif_displaymessage(sd->fd, jstrescape(message));
}
- if(!new) {
- clif_displaymessage(sd->fd, "You have no new messages.");
+ if(!new_) {
+ //clif_displaymessage(sd->fd, "You have no new messages.");
+ clif_displaymessage(sd->fd, msg_txt(516));
}
return 0;
@@ -109,9 +117,8 @@ int mail_read(struct map_session_data *sd, int message_id)
char message[80];
- if(sd==NULL)
- return 0;
-
+ nullpo_retr (0, sd);
+
sprintf(tmp_msql,"SELECT `message_id`,`to_account_id`,`from_char_name`,`message`,`read_flag`,`priority`,`check_flag` from `%s` WHERE `to_account_id` = \"%d\" ORDER by `message_id` LIMIT %d, 1",mail_db,sd->status.account_id,message_id-1);
if (mysql_query(&mail_handle, tmp_msql)) {
@@ -121,48 +128,47 @@ int mail_read(struct map_session_data *sd, int message_id)
mail_res = mysql_store_result(&mail_handle);
if(mail_res) {
- if (mysql_num_rows(mail_res) == 0) {
- mysql_free_result(mail_res);
- clif_displaymessage(sd->fd, "Message not found.");
- return 0;
- }
-
- if ((mail_row = mysql_fetch_row(mail_res))) {
+ if (mysql_num_rows(mail_res) == 0) {
+ mysql_free_result(mail_res);
+ //clif_displaymessage(sd->fd, "Message not found.");
+ clif_displaymessage(sd->fd, msg_txt(517));
+ return 0;
+ }
+ if ((mail_row = mysql_fetch_row(mail_res))) {
if(!atoi(mail_row[6])) {
sprintf(tmp_msql,"UPDATE `%s` SET `check_flag`='1' WHERE `message_id`= \"%d\"", mail_db, atoi(mail_row[0]));
- if(mysql_query(&mail_handle, tmp_msql) ) {
- printf("DB server Error (update Read `%s`)- %s\n", mail_db, mysql_error(&mail_handle) );
- }
+ if(mysql_query(&mail_handle, tmp_msql) ) {
+ printf("DB server Error (update Read `%s`)- %s\n", mail_db, mysql_error(&mail_handle) );
+ }
}
- sprintf(message, "Reading message from %s", mail_row[2]);
- clif_displaymessage(sd->fd, message);
+ //sprintf(message, "Reading message from %s", mail_row[2]);
+ sprintf(message, msg_txt(518), mail_row[2]);
+ clif_displaymessage(sd->fd, jstrescape(message));
sprintf(message, "%s", mail_row[3]);
- clif_displaymessage(sd->fd, message);
+ clif_displaymessage(sd->fd, jstrescape(message));
sprintf(tmp_msql,"UPDATE `%s` SET `read_flag`='1' WHERE `message_id`= \"%d\"", mail_db, atoi(mail_row[0]));
- if(mysql_query(&mail_handle, tmp_msql) ) {
+ if(mysql_query(&mail_handle, tmp_msql) ) {
printf("DB server Error (update Read `%s`)- %s\n", mail_db, mysql_error(&mail_handle) );
- }
+ }
}
-
+
mysql_free_result(mail_res);
-
+
} else {
- printf("MySQL error (storing query result for %s): %s\n", mail_db, mysql_error(&mail_handle));
- return 0;
- }
+ printf("MySQL error (storing query result for %s): %s\n", mail_db, mysql_error(&mail_handle));
+ }
return 0;
}
int mail_delete(struct map_session_data *sd, int message_id)
{
- if(sd==NULL)
- return 0;
-
+ nullpo_retr (0, sd);
+
sprintf(tmp_msql,"SELECT `message_id`,`to_account_id`,`read_flag`,`priority`,`check_flag` from `%s` WHERE `to_account_id` = \"%d\" ORDER by `message_id` LIMIT %d, 1",mail_db,sd->status.account_id,message_id-1);
if (mysql_query(&mail_handle, tmp_msql)) {
@@ -172,21 +178,25 @@ int mail_delete(struct map_session_data *sd, int message_id)
mail_res = mysql_store_result(&mail_handle);
if(mail_res) {
- if (mysql_num_rows(mail_res) == 0) {
- mysql_free_result(mail_res);
- clif_displaymessage(sd->fd, "Message not found.");
- return 0;
- }
+ if (mysql_num_rows(mail_res) == 0) {
+ mysql_free_result(mail_res);
+ //clif_displaymessage(sd->fd, "Message not found.");
+ clif_displaymessage(sd->fd, msg_txt(517));
+ return 0;
+ }
- if ((mail_row = mysql_fetch_row(mail_res))) {
+ if ((mail_row = mysql_fetch_row(mail_res))) {
if(!atoi(mail_row[2]) && atoi(mail_row[3])) {
mysql_free_result(mail_res);
- clif_displaymessage(sd->fd,"Cannot delete unread priority mail.");
+ //clif_displaymessage(sd->fd,"Cannot delete unread priority mail.");
+ clif_displaymessage(sd->fd,msg_txt(519));
+
return 0;
}
if(!atoi(mail_row[4])) {
mysql_free_result(mail_res);
- clif_displaymessage(sd->fd,"You have recieved new mail, use @listmail before deleting.");
+ //clif_displaymessage(sd->fd,"You have recieved new mail, use @listmail before deleting.");
+ clif_displaymessage(sd->fd,msg_txt(520));
return 0;
}
sprintf(tmp_msql,"DELETE FROM `%s` WHERE `message_id` = \"%d\"", mail_db, atoi(mail_row[0]));
@@ -195,75 +205,77 @@ int mail_delete(struct map_session_data *sd, int message_id)
printf("DB server Error (update Read `%s`)- %s\n", mail_db, mysql_error(&mail_handle) );
return 0;
}
- else clif_displaymessage(sd->fd,"Message deleted.");
+ //else clif_displaymessage(sd->fd,"Message deleted.");
+ else clif_displaymessage(sd->fd,msg_txt(521));
}
-
+
mysql_free_result(mail_res);
-
+
} else {
- printf("MySQL error (delete query result for %s): %s\n", mail_db, mysql_error(&mail_handle));
- return 0;
- }
+ printf("MySQL error (delete query result for %s): %s\n", mail_db, mysql_error(&mail_handle));
+ }
return 0;
}
int mail_send(struct map_session_data *sd, char *name, char *message, int flag)
{
- if(sd==NULL)
- return 0;
-
+ nullpo_retr (0, sd);
+
if(pc_isGM(sd) < 80 && sd->mail_counter > 0) {
- clif_displaymessage(sd->fd,"You must wait 10 minutes before sending another message");
+ //clif_displaymessage(sd->fd,"You must wait 10 minutes before sending another message");
+ clif_displaymessage(sd->fd,msg_txt(522));
return 0;
}
if(strcmp(name,"*")==0) {
if(pc_isGM(sd) < 80) {
- clif_displaymessage(sd->fd, "Access Denied.");
+ //clif_displaymessage(sd->fd, "Access Denied.");
+ clif_displaymessage(sd->fd, msg_txt(523));
return 0;
}
else
sprintf(tmp_msql,"SELECT DISTINCT `account_id` FROM `%s` WHERE `account_id` <> '%d' ORDER BY `account_id`", char_db, sd->status.account_id);
}
else
- sprintf(tmp_msql,"SELECT `account_id`,`name` FROM `%s` WHERE `name` = \"%s\"", char_db, name);
+ sprintf(tmp_msql,"SELECT `account_id`,`name` FROM `%s` WHERE `name` = \"%s\"", char_db, jstrescape(name));
if (mysql_query(&mail_handle, tmp_msql)) {
printf("Database server error (executing query for %s): %s\n", char_db, mysql_error(&mail_handle));
return 0;
- }
-
+ }
+
mail_res = mysql_store_result(&mail_handle);
if(mail_res) {
- if (mysql_num_rows(mail_res) == 0) {
+ if (mysql_num_rows(mail_res) == 0) {
mysql_free_result(mail_res);
- clif_displaymessage(sd->fd,"Character does not exist.");
- return 0;
- }
+ //clif_displaymessage(sd->fd,"Character does not exist.");
+ clif_displaymessage(sd->fd,msg_txt(524));
+ return 0;
+ }
- while ((mail_row = mysql_fetch_row(mail_res))) {
+ while ((mail_row = mysql_fetch_row(mail_res))) {
if(strcmp(name,"*")==0) {
- sprintf(tmp_msql, "INSERT INTO `%s` (`to_account_id`,`from_account_id`,`from_char_name`,`message`,`priority`)"
- " VALUES ('%d', '%d', '%s', '%s', '%d')",mail_db, atoi(mail_row[0]), sd->status.account_id, sd->status.name, message, flag);
+ sprintf(tmp_msql, "INSERT DELAYED INTO `%s` (`to_account_id`,`from_account_id`,`from_char_name`,`message`,`priority`)"
+ " VALUES ('%d', '%d', '%s', '%s', '%d')",mail_db, atoi(mail_row[0]), sd->status.account_id, sd->status.name, jstrescape(message), flag);
}
else {
- sprintf(tmp_msql, "INSERT INTO `%s` (`to_account_id`,`to_char_name`,`from_account_id`,`from_char_name`,`message`,`priority`)"
- " VALUES ('%d', '%s', '%d', '%s', '%s', '%d')",mail_db, atoi(mail_row[0]), mail_row[1], sd->status.account_id, sd->status.name, message, flag);
+ sprintf(tmp_msql, "INSERT DELAYED INTO `%s` (`to_account_id`,`to_char_name`,`from_account_id`,`from_char_name`,`message`,`priority`)"
+ " VALUES ('%d', '%s', '%d', '%s', '%s', '%d')",mail_db, atoi(mail_row[0]), mail_row[1], sd->status.account_id, sd->status.name, jstrescape(message), flag);
if(pc_isGM(sd) < 80)
sd->mail_counter=5;
}
-
+
if(mysql_query(&mail_handle, tmp_msql) ) {
mysql_free_result(mail_res);
printf("DB server Error (insert `mail_db`)- %s\n", mysql_error(&mail_handle) );
return 0;
}
-
}
}
- clif_displaymessage(sd->fd,"Mail has been sent.");
+ //clif_displaymessage(sd->fd,"Mail has been sent.");
+ clif_displaymessage(sd->fd,msg_txt(525));
return 0;
}
@@ -271,43 +283,43 @@ int mail_send(struct map_session_data *sd, char *name, char *message, int flag)
int mail_check_timer(int tid,unsigned int tick,int id,int data)
{
struct map_session_data *sd = NULL;
- int i;
+ int i;
if(mail_timer != tid)
return 0;
sprintf(tmp_msql,"SELECT DISTINCT `to_account_id` FROM `%s` WHERE `read_flag` = '0' AND `check_flag` = '0'", mail_db);
-
+
if (mysql_query(&mail_handle, tmp_msql)) {
printf("Database server error (executing query for %s): %s\n", char_db, mysql_error(&mail_handle));
mail_timer=add_timer(gettick()+MAIL_CHECK_TIME,mail_check_timer,0,0);
return 0;
- }
+ }
mail_res = mysql_store_result(&mail_handle);
if (mail_res) {
-
- if (mysql_num_rows(mail_res) == 0) {
+ if (mysql_num_rows(mail_res) == 0) {
mysql_free_result(mail_res);
mail_timer=add_timer(gettick()+MAIL_CHECK_TIME,mail_check_timer,0,0);
- return 0;
- }
+ return 0;
+ }
- while ((mail_row = mysql_fetch_row(mail_res))) {
+ while ((mail_row = mysql_fetch_row(mail_res))) {
for (i = 0; i < fd_max; i++) {
- if (session[i] && (sd = session[i]->session_data) && sd->state.auth){
+ if (session[i] && (sd = (struct map_session_data *) session[i]->session_data) && sd->state.auth){
if(pc_isGM(sd) < 80 && sd->mail_counter > 0)
sd->mail_counter--;
if(sd->status.account_id==atoi(mail_row[0]))
- clif_displaymessage(sd->fd, "You have new mail.");
+ //clif_displaymessage(sd->fd, "You have new mail.");
+ clif_displaymessage(sd->fd, msg_txt(526));
}
}
}
}
sprintf(tmp_msql,"UPDATE `%s` SET `check_flag`='1' WHERE `check_flag`= '0' ", mail_db);
- if(mysql_query(&mail_handle, tmp_msql) ) {
+ if(mysql_query(&mail_handle, tmp_msql) ) {
printf("DB server Error (update Read `%s`)- %s\n", mail_db, mysql_error(&mail_handle) );
}
@@ -316,9 +328,10 @@ int mail_check_timer(int tid,unsigned int tick,int id,int data)
}
int do_init_mail(void)
-{
+{
add_timer_func_list(mail_check_timer,"mail_check_timer");
mail_timer=add_timer(gettick()+MAIL_CHECK_TIME,mail_check_timer,0,0);
return 0;
}
+#endif
diff --git a/src/map/map.c b/src/map/map.c
index 3214373f9..386b38954 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -8,12 +8,14 @@
#else
#include <netdb.h>
#endif
+#include <math.h>
#include "core.h"
#include "timer.h"
#include "db.h"
#include "grfio.h"
#include "malloc.h"
+#include "version.h"
#include "map.h"
#include "chrif.h"
@@ -21,6 +23,7 @@
#include "intif.h"
#include "npc.h"
#include "pc.h"
+#include "status.h"
#include "mob.h"
#include "chat.h"
#include "itemdb.h"
@@ -43,7 +46,8 @@
#include "memwatch.h"
#endif
-unsigned long ticks = 0; // by MC Cameri
+// maybe put basic macros to somewhere else
+#define swap(a,b) ((a == b) || ((a ^= b), (b ^= a), (a ^= b)))
#ifndef TXT_ONLY
@@ -99,19 +103,31 @@ int read_gm_interval = 600000;
char char_db[32] = "char";
static int online_timer(int,unsigned int,int,int);
-
int CHECK_INTERVAL = 3600000; // [Valaris]
-int check_online_timer=0; // [Valaris]
#endif /* not TXT_ONLY */
-// ‹É—Í static‚Ń[ƒJƒ‹‚ÉŽû‚ß‚é
+
+char *INTER_CONF_NAME;
+char *LOG_CONF_NAME;
+char *MAP_CONF_NAME;
+char *BATTLE_CONF_FILENAME;
+char *ATCOMMAND_CONF_FILENAME;
+char *CHARCOMMAND_CONF_FILENAME;
+char *SCRIPT_CONF_NAME;
+char *MSG_CONF_NAME;
+char *GRF_PATH_FILENAME;
+
+#define USE_AFM
+#define USE_AF2
+
+// ‹É—Í static‚Ń?ƒJƒ‹‚É?‚ß‚é
static struct dbt * id_db=NULL;
static struct dbt * map_db=NULL;
static struct dbt * nick_db=NULL;
static struct dbt * charid_db=NULL;
static int users=0;
-static struct block_list *object[MAX_FLOORITEM];
+static struct block_list *objects[MAX_FLOORITEM];
static int first_free_object_id=0,last_object_id=0;
#define block_free_max 1048576
@@ -145,23 +161,33 @@ struct charid2nick {
int req_id;
};
+// «Þ«Ã«×«­«ã«Ã«·«å××éīի髰(map_athana.conf?ªÎread_map_from_cacheªÇò¦E)
+// 0:××éĪ·ªÊª¤ 1:Þª?õêÜÁðí 2:?õêÜÁðí
+int map_read_flag = READ_FROM_GAT;
+char map_cache_file[256]="db/map.info"; // «Þ«Ã«×«­«ã«Ã«·«å«Õ«¡«¤«E£
+
char motd_txt[256] = "conf/motd.txt";
char help_txt[256] = "conf/help.txt";
char wisp_server_name[24] = "Server"; // can be modified in char-server configuration file
int console = 0;
+
/*==========================================
- * ‘SmapŽI‘Œv‚Å‚ÌÚ‘±”Ý’è
+ * ‘SmapŽI?Œv‚Å‚ÌÚ??Ý’è
* (charŽI‚©‚ç‘—‚ç‚ê‚Ä‚­‚é)
*------------------------------------------
*/
-void map_setusers(int n) {
- users = n;
+void map_setusers(int fd)
+{
+ users = RFIFOL(fd,2);
+ // send some anser
+ WFIFOW(fd,0) = 0x2718;
+ WFIFOSET(fd,2);
}
/*==========================================
- * ‘SmapŽI‘Œv‚Å‚ÌÚ‘±”Žæ“¾ (/w‚ւ̉ž“š—p)
+ * ‘SmapŽI?Œv‚Å‚ÌÚ??Žæ“¾ (/w‚Ö‚Ì?“š—p)
*------------------------------------------
*/
int map_getusers(void) {
@@ -169,18 +195,18 @@ int map_getusers(void) {
}
//
-// block휂̈À‘S«Šm•Ûˆ—
+// block휂̈À‘S«Šm•Û?—
//
/*==========================================
- * block‚ðfree‚·‚邯‚«free‚̕ςí‚è‚ɌĂÔ
+ * block‚ðfree‚·‚邯‚«free‚Ì?‚í‚è‚ɌĂÔ
* ƒƒbƒN‚³‚ê‚Ä‚¢‚邯‚«‚̓oƒbƒtƒ@‚É‚½‚ß‚é
*------------------------------------------
*/
int map_freeblock( void *bl )
{
if(block_free_lock==0){
- free(bl);
+ aFree(bl);
bl = NULL;
}
else{
@@ -216,23 +242,40 @@ int map_freeblock_unlock(void) {
// printf("map_freeblock_unlock: free %d object\n",block_free_count);
// }
for(i=0;i<block_free_count;i++){
- free(block_free[i]);
+ aFree(block_free[i]);
block_free[i] = NULL;
}
block_free_count=0;
}else if(block_free_lock<0){
if(battle_config.error_log)
printf("map_freeblock_unlock: lock count < 0 !\n");
+ block_free_lock = 0; // ŽŸ‰ñˆÈ~‚̃ƒbƒN‚ÉŽxႪo‚Ä‚­‚é‚Ì‚ÅƒŠƒZƒbƒg
}
return block_free_lock;
}
+// map_freeblock_lock() ‚ðŒÄ‚ñ‚Å map_freeblock_unlock() ‚ðŒÄ‚΂Ȃ¢
+// ŠÖ”‚ª‚ ‚Á‚½‚Ì‚ÅA’èŠú“I‚Éblock_free_lock‚ðƒŠƒZƒbƒg‚·‚邿‚¤‚É‚·‚éB
+// ‚±‚ÌŠÖ”‚ÍAdo_timer() ‚̃gƒbƒvƒŒƒxƒ‹‚©‚çŒÄ‚΂ê‚é‚Ì‚ÅA
+// block_free_lock ‚ð’¼Ú‚¢‚¶‚Á‚Ä‚àŽxá–³‚¢‚Í‚¸B
+
+int map_freeblock_timer(int tid,unsigned int tick,int id,int data) {
+ if(block_free_lock > 0) {
+ printf("map_freeblock_timer: block_free_lock(%d) is invalid.\n",block_free_lock);
+ block_free_lock = 1;
+ map_freeblock_unlock();
+ }
+ // else {
+ // printf("map_freeblock_timer: check ok\n");
+ // }
+ return 0;
+}
//
-// block‰»ˆ—
+// block‰»?—
//
/*==========================================
- * map[]‚Ìblock_list‚©‚çŒq‚ª‚Á‚Ä‚¢‚éꇂÉ
+ * map[]‚Ìblock_list‚©‚ç?‚ª‚Á‚Ä‚¢‚éꇂÉ
* bl->prev‚Ébl_head‚̃AƒhƒŒƒX‚ð“ü‚ê‚Ä‚¨‚­
*------------------------------------------
*/
@@ -240,9 +283,9 @@ static struct block_list bl_head;
/*==========================================
* map[]‚Ìblock_list‚ɒljÁ
- * mob‚Í”‚ª‘½‚¢‚Ì‚Å•ÊƒŠƒXƒg
+ * mob‚Í?‚ª‘½‚¢‚Ì‚Å•ÊƒŠƒXƒg
*
- * Šù‚Élinkς݂©‚ÌŠm”F‚ª–³‚¢BŠëŒ¯‚©‚à
+ * ?‚Élink?‚Ý‚©‚ÌŠm”F‚ª–³‚¢BŠë?‚©‚à
*------------------------------------------
*/
int map_addblock(struct block_list *bl)
@@ -286,7 +329,7 @@ int map_addblock(struct block_list *bl)
/*==========================================
* map[]‚Ìblock_list‚©‚çŠO‚·
- * prev‚ªNULL‚Ìê‡list‚ÉŒq‚ª‚Á‚ĂȂ¢
+ * prev‚ªNULL‚Ìê‡list‚É?‚ª‚Á‚ĂȂ¢
*------------------------------------------
*/
int map_delblock(struct block_list *bl)
@@ -294,7 +337,7 @@ int map_delblock(struct block_list *bl)
int b;
nullpo_retr(0, bl);
- // Šù‚Éblocklist‚©‚甲‚¯‚Ä‚¢‚é
+ // ?‚Éblocklist‚©‚ç?‚¯‚Ä‚¢‚é
if(bl->prev==NULL){
if(bl->next!=NULL){
// prev‚ªNULL‚Ånext‚ªNULL‚łȂ¢‚̂͗L‚Á‚Ă͂Ȃç‚È‚¢
@@ -308,7 +351,8 @@ int map_delblock(struct block_list *bl)
if(bl->type==BL_PC)
map[bl->m].users--;
- if(bl->next) bl->next->prev = bl->prev;
+ if(bl->next)
+ bl->next->prev = bl->prev;
if(bl->prev==&bl_head){
// ƒŠƒXƒg‚Ì“ª‚Ȃ̂ÅAmap[]‚Ìblock_list‚ðXV‚·‚é
if(bl->type==BL_MOB){
@@ -330,7 +374,7 @@ int map_delblock(struct block_list *bl)
}
/*==========================================
- * ŽüˆÍ‚ÌPCl”‚𔂦‚é (Œ»Ý–¢Žg—p)
+ * Žü?‚ÌPCl?‚ð?‚¦‚é (Œ»Ý–¢Žg—p)
*------------------------------------------
*/
int map_countnearpc(int m, int x, int y) {
@@ -356,7 +400,7 @@ int map_countnearpc(int m, int x, int y) {
}
/*==========================================
- * ƒZƒ‹ã‚ÌPC‚ÆMOB‚Ì”‚𔂦‚é (ƒOƒ‰ƒ“ƒhƒNƒƒX—p)
+ * ƒZƒ‹ã‚ÌPC‚ÆMOB‚Ì?‚ð?‚¦‚é (ƒOƒ‰ƒ“ƒhƒNƒƒX—p)
*------------------------------------------
*/
int map_count_oncell(int m, int x, int y) {
@@ -383,18 +427,47 @@ int map_count_oncell(int m, int x, int y) {
if(!count) count = 1;
return count;
}
+/*
+ * «»«E¾ªÎõÌôøªË̸ªÄª±ª¿«¹«­«Eæ«Ë«Ã«ÈªòÚ÷ª¹
+ */
+struct skill_unit *map_find_skill_unit_oncell(struct block_list *target,int x,int y,int skill_id,struct skill_unit *out_unit)
+{
+ int m,bx,by;
+ struct block_list *bl;
+ int i,c;
+ struct skill_unit *unit;
+ m = target->m;
+ if (x < 0 || y < 0 || (x >= map[m].xs) || (y >= map[m].ys))
+ return NULL;
+ bx = x/BLOCK_SIZE;
+ by = y/BLOCK_SIZE;
+
+ bl = map[m].block[bx+by*map[m].bxs];
+ c = map[m].block_count[bx+by*map[m].bxs];
+ for(i=0;i<c && bl;i++,bl=bl->next){
+ if (bl->x != x || bl->y != y || bl->type != BL_SKILL)
+ continue;
+ unit = (struct skill_unit *) bl;
+ if (unit==out_unit || !unit->alive ||
+ !unit->group || unit->group->skill_id!=skill_id)
+ continue;
+ if (battle_check_target(&unit->bl,target,unit->group->target_flag)>0)
+ return unit;
+ }
+ return NULL;
+}
/*==========================================
- * map m (x0,y0)-(x1,y1)“à‚Ì‘Sobj‚ɑ΂µ‚Ä
+ * map m (x0,y0)-(x1,y1)?‚Ì‘Sobj‚É?‚µ‚Ä
* func‚ðŒÄ‚Ô
* type!=0 ‚Ȃ炻‚ÌŽí—Þ‚Ì‚Ý
*------------------------------------------
*/
void map_foreachinarea(int (*func)(struct block_list*,va_list),int m,int x0,int y0,int x1,int y1,int type,...) {
+ va_list ap;
int bx,by;
struct block_list *bl=NULL;
- va_list ap=NULL;
int blockcount=bl_list_count,i,c;
if(m < 0)
@@ -437,7 +510,7 @@ void map_foreachinarea(int (*func)(struct block_list*,va_list),int m,int x0,int
map_freeblock_lock(); // ƒƒ‚ƒŠ‚©‚ç‚̉ð•ú‚ð‹ÖŽ~‚·‚é
for(i=blockcount;i<bl_list_count;i++)
- if(bl_list[i]->prev) // —LŒø‚©‚Ç‚¤‚©ƒ`ƒFƒbƒN
+ if(bl_list[i]->prev) // —L?‚©‚Ç‚¤‚©ƒ`ƒFƒbƒN
func(bl_list[i],ap);
map_freeblock_unlock(); // ‰ð•ú‚ð‹–‰Â‚·‚é
@@ -448,8 +521,8 @@ void map_foreachinarea(int (*func)(struct block_list*,va_list),int m,int x0,int
/*==========================================
* ‹éŒ`(x0,y0)-(x1,y1)‚ª(dx,dy)ˆÚ“®‚µ‚½Žž‚Ì
- * —̈æŠO‚ɂȂé—̈æ(‹éŒ`‚©LŽšŒ`)“à‚Ìobj‚É
- * ‘΂µ‚Äfunc‚ðŒÄ‚Ô
+ * —̈æŠO‚ɂȂé—̈æ(‹éŒ`‚©LŽšŒ`)?‚Ìobj‚É
+ * ?‚µ‚Äfunc‚ðŒÄ‚Ô
*
* dx,dy‚Í-1,0,1‚݂̂Ƃ·‚éi‚Ç‚ñ‚È’l‚Å‚à‚¢‚¢‚Á‚Û‚¢Hj
*------------------------------------------
@@ -457,7 +530,7 @@ void map_foreachinarea(int (*func)(struct block_list*,va_list),int m,int x0,int
void map_foreachinmovearea(int (*func)(struct block_list*,va_list),int m,int x0,int y0,int x1,int y1,int dx,int dy,int type,...) {
int bx,by;
struct block_list *bl=NULL;
- va_list ap=NULL;
+ va_list ap;
int blockcount=bl_list_count,i,c;
va_start(ap,type);
@@ -546,8 +619,12 @@ void map_foreachinmovearea(int (*func)(struct block_list*,va_list),int m,int x0,
map_freeblock_lock(); // ƒƒ‚ƒŠ‚©‚ç‚̉ð•ú‚ð‹ÖŽ~‚·‚é
for(i=blockcount;i<bl_list_count;i++)
- if(bl_list[i]->prev) // —LŒø‚©‚Ç‚¤‚©ƒ`ƒFƒbƒN
+ if(bl_list[i]->prev) { // —L?‚©‚Ç‚¤‚©ƒ`ƒFƒbƒN
+ if (bl_list[i]->type == BL_PC
+ && session[((struct map_session_data *) bl_list[i])->fd] == NULL)
+ continue;
func(bl_list[i],ap);
+ }
map_freeblock_unlock(); // ‰ð•ú‚ð‹–‰Â‚·‚é
@@ -562,7 +639,7 @@ void map_foreachinmovearea(int (*func)(struct block_list*,va_list),int m,int x0,
void map_foreachincell(int (*func)(struct block_list*,va_list),int m,int x,int y,int type,...) {
int bx,by;
struct block_list *bl=NULL;
- va_list ap=NULL;
+ va_list ap;
int blockcount=bl_list_count,i,c;
va_start(ap,type);
@@ -602,18 +679,445 @@ void map_foreachincell(int (*func)(struct block_list*,va_list),int m,int x,int y
map_freeblock_lock(); // ƒƒ‚ƒŠ‚©‚ç‚̉ð•ú‚ð‹ÖŽ~‚·‚é
for(i=blockcount;i<bl_list_count;i++)
- if(bl_list[i]->prev) // —LŒø‚©‚Ç‚¤‚©ƒ`ƒFƒbƒN
+ if(bl_list[i]->prev) // —L?‚©‚Ç‚¤‚©ƒ`ƒFƒbƒN
+ func(bl_list[i],ap);
+
+ map_freeblock_unlock(); // ‰ð•ú‚ð‹–‰Â‚·‚é
+
+ va_end(ap);
+ bl_list_count = blockcount;
+}
+
+/*============================================================
+* For checking a path between two points (x0, y0) and (x1, y1)
+*------------------------------------------------------------
+ */
+void map_foreachinpath(int (*func)(struct block_list*,va_list),int m,int x0,int y0,int x1,int y1,int range,int type,...)
+{
+/* va_list ap;
+ double deltax = 0.0;
+ double deltay = 0.0;
+ int t, bx, by;
+ int *xs, *ys;
+ int blockcount = bl_list_count, i, c;
+ struct block_list *bl = NULL;
+
+ if(m < 0)
+ return;
+ va_start(ap,type);
+ if (x0 < 0) x0 = 0;
+ if (y0 < 0) y0 = 0;
+ if (x1 >= map[m].xs) x1 = map[m].xs-1;
+ if (y1 >= map[m].ys) y1 = map[m].ys-1;
+
+ // I'm not finished thinking on it
+ // but first it might better use a parameter equation
+ // x=(x1-x0)*t+x0; y=(y1-y0)*t+y0; t=[0,1]
+ // would not need special case aproximating for infinity/zero slope
+ // so maybe this way:
+
+ // find maximum runindex
+ int tmax = abs(y1-y0);
+ if(tmax < abs(x1-x0))
+ tmax = abs(x1-x0);
+
+ xs = (int *)aCallocA(tmax + 1, sizeof(int));
+ ys = (int *)aCallocA(tmax + 1, sizeof(int));
+
+ // pre-calculate delta values for x and y destination
+ // should speed up cause you don't need to divide in the loop
+ if(tmax>0)
+ {
+ deltax = ((double)(x1-x0)) / ((double)tmax);
+ deltay = ((double)(y1-y0)) / ((double)tmax);
+ }
+ // go along the index
+ for(t=0; t<=tmax; t++)
+ {
+ int x = (int)floor(deltax * (double)t +0.5)+x0;
+ int y = (int)floor(deltay * (double)t +0.5)+y0;
+ // the xy pairs of points in line between x0y0 and x1y1
+ // including start and end point
+ xs[t] = x;
+ ys[t] = y;
+ }
+
+ if (type == 0 || type != BL_MOB)
+
+
+this here is wrong,
+there is no check if x0<x1 and y0<y1
+but this is not valid in 3 of 4 cases,
+so in this case here you check only blocks when shooting to a positive direction
+shooting in other directions just do nothing like the skill has failed
+if you want to keep this that way then check and swap x0,y0 with x1,y1
+
+ for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) {
+ for(bx=x0/BLOCK_SIZE;bx<=x1/BLOCK_SIZE;bx++){
+ bl = map[m].block[bx+by*map[m].bxs];
+ c = map[m].block_count[bx+by*map[m].bxs];
+ for(i=0;i<c && bl;i++,bl=bl->next){
+ if(bl) {
+ if (type && bl->type!=type)
+ continue;
+ for(t=0; t<=tmax; t++)
+ if(bl->x==xs[t] && bl->y==ys[t] && bl_list_count<BL_LIST_MAX)
+ bl_list[bl_list_count++]=bl;
+ }
+ }
+ }
+ }
+ if(type==0 || type==BL_MOB)
+ for(by=y0/BLOCK_SIZE;by<=y1/BLOCK_SIZE;by++){
+ for(bx=x0/BLOCK_SIZE;bx<=x1/BLOCK_SIZE;bx++){
+ bl = map[m].block_mob[bx+by*map[m].bxs];
+ c = map[m].block_mob_count[bx+by*map[m].bxs];
+ for(i=0;i<c && bl;i++,bl=bl->next){
+ if(bl) {
+ for(t=0; t<=tmax; t++)
+ if(bl->x==xs[t] && bl->y==ys[t] && bl_list_count<BL_LIST_MAX)
+ bl_list[bl_list_count++]=bl;
+ }
+ }
+ }
+ }
+
+ if(bl_list_count>=BL_LIST_MAX) {
+ if(battle_config.error_log)
+ printf("map_foreachinarea: *WARNING* block count too many!\n");
+ }
+
+ map_freeblock_lock(); // ƒƒ‚ƒŠ‚©‚ç‚̉ð•ú‚ð‹ÖŽ~‚·‚é
+
+ for(i=blockcount;i<bl_list_count;i++)
+ if(bl_list[i]->prev) // —L?‚©‚Ç‚¤‚©ƒ`ƒFƒbƒN
func(bl_list[i],ap);
map_freeblock_unlock(); // ‰ð•ú‚ð‹–‰Â‚·‚é
+ bl_list_count = blockcount;
+ aFree (xs);
+ aFree (ys);
+ va_end(ap);
+
+*/
+
+/*
+//////////////////////////////////////////////////////////////
+//
+// sharp shooting 1
+//
+//////////////////////////////////////////////////////////////
+// problem:
+// finding targets standing on and within some range of a line
+// (t1,t2 t3 and t4 get hit)
+//
+// target 1
+// x t4
+// t2
+// t3 x
+// x
+// S
+//////////////////////////////////////////////////////////////
+// solution 1 (straight forward, but a bit calculation expensive)
+// calculating perpendiculars from quesionable mobs to the straight line
+// if the mob is hit then depends on the distance to the line
+//
+// solution 2 (complex, need to handle many cases, but maybe faster)
+// make a formula to deside if a given (x,y) is within a shooting area
+// the shape can be ie. rectangular or triangular
+// if the mob is hit then depends on if the mob is inside or outside the area
+// I'm not going to implement this, but if somebody is interested
+// in vector algebra, it might be some fun
+
+//////////////////////////////////////////////////////////////
+// possible shooting ranges (I prefer the second one)
+//////////////////////////////////////////////////////////////
+//
+// ---------------- ------
+// ---------------- ------------
+// Sxxxxxxxxxxxxxxxxtarget Sxxxxxxxxxxxxxxxxtarget
+// ---------------- ------------
+// ---------------- -----
+//
+// the original code implemented the left structure
+// might be not that realistic, so I changed to the other one
+// I take "range" as max distance from the line
+//////////////////////////////////////////////////////////////
+
+ va_list ap;
+ int i, blockcount = bl_list_count;
+ struct block_list *bl;
+ int c1,c2;
+
+///////////
+ double deltax,deltay;
+ double k,kfact,knorm;
+ double v1,v2,distance;
+ double xm,ym,rd;
+ int bx,by,bx0,bx1,by0,by1;
+//////////////
+ // no map
+ if(m < 0) return;
+
+ // xy out of range
+ if (x0 < 0) x0 = 0;
+ if (y0 < 0) y0 = 0;
+ if (x1 >= map[m].xs) x1 = map[m].xs-1;
+ if (y1 >= map[m].ys) y1 = map[m].ys-1;
+
+ ///////////////////////////////
+ // stuff for a linear equation in xy coord to calculate
+ // the perpendicular from a block xy to the straight line
+ deltax = (x1-x0);
+ deltay = (y1-y0);
+ kfact = (deltax*deltax+deltay*deltay); // the sqare length of the line
+ knorm = -deltax*x0-deltay*y0; // the offset vector param
+
+//printf("(%i,%i)(%i,%i) range: %i\n",x0,y0,x1,y1,range);
+
+ if(kfact==0) return; // shooting at the standing position should not happen
+ kfact = 1/kfact; // divide here and multiply in the loop
+
+ range *= range; // compare with range^2 so we can skip a sqrt and signs
+
+ ///////////////////////////////
+ // prepare shooting area check
+ xm = (x1+x0)/2.0;
+ ym = (y1+y0)/2.0;// middle point on the shooting line
+ // the sqared radius of a circle around the shooting range
+ // plus the sqared radius of a block
+ rd = (x0-xm)*(x0-xm) + (y0-ym)*(y0-ym) + (range*range)
+ +BLOCK_SIZE*BLOCK_SIZE/2;
+ // so whenever a block midpoint is within this circle
+ // some of the block area is possibly within the shooting range
+
+ ///////////////////////////////
+ // what blocks we need to test
+ // blocks covered by the xy position of begin and end of the line
+ bx0 = x0/BLOCK_SIZE;
+ bx1 = x1/BLOCK_SIZE;
+ by0 = y0/BLOCK_SIZE;
+ by1 = y1/BLOCK_SIZE;
+ // swap'em for a smallest-to-biggest run
+ if(bx0>bx1) swap(bx0,bx1);
+ if(by0>by1) swap(by0,by1);
+
+ // enlarge the block area by a range value and 1
+ // so we can be sure to process all blocks that might touch the shooting area
+ // in this case here with BLOCK_SIZE=8 and range=2 it will be only enlarged by 1
+ // but I implement it anyway just in case that ranges will be larger
+ // or BLOCK_SIZE smaller in future
+ i = (range/BLOCK_SIZE+1);//temp value
+ if(bx0>i) bx0 -=i; else bx0=0;
+ if(by0>i) by0 -=i; else by0=0;
+ if(bx1+i<map[m].bxs) bx1 +=i; else bx1=map[m].bxs-1;
+ if(by1+i<map[m].bys) by1 +=i; else by1=map[m].bys-1;
+
+
+//printf("run for (%i,%i)(%i,%i)\n",bx0,by0,bx1,by1);
+ for(bx=bx0; bx<=bx1; bx++)
+ for(by=by0; by<=by1; by++)
+ { // block xy
+ c1 = map[m].block_count[bx+by*map[m].bxs]; // number of elements in the block
+ c2 = map[m].block_mob_count[bx+by*map[m].bxs]; // number of mobs in the mob block
+ if( (c1==0) && (c2==0) ) continue; // skip if nothing in the blocks
+
+//printf("block(%i,%i) %i %i\n",bx,by,c1,c2);fflush(stdout);
+ // test if the mid-point of the block is too far away
+ // so we could skip the whole block in this case
+ v1 = (bx*BLOCK_SIZE+BLOCK_SIZE/2-xm)*(bx*BLOCK_SIZE+BLOCK_SIZE/2-xm)
+ +(by*BLOCK_SIZE+BLOCK_SIZE/2-ym)*(by*BLOCK_SIZE+BLOCK_SIZE/2-ym);
+//printf("block(%i,%i) v1=%f rd=%f\n",bx,by,v1,rd);fflush(stdout);
+ // check for the worst case scenario
+ if(v1 > rd) continue;
+
+ // it seems that the block is at least partially covered by the shooting range
+ // so we go into it
+ if(type==0 || type!=BL_MOB) {
+ bl = map[m].block[bx+by*map[m].bxs]; // a block with the elements
+ for(i=0;i<c1 && bl;i++,bl=bl->next){ // go through all elements
+ if( bl && ( !type || bl->type==type ) && bl_list_count<BL_LIST_MAX )
+ {
+ // calculate the perpendicular from block xy to the straight line
+ k = kfact*(deltax*bl->x + deltay*bl->y + knorm);
+ // check if the perpendicular is within start and end of our line
+ if(k>=0 && k<=1)
+ { // calculate the distance
+ v1 = deltax*k+x0 - bl->x;
+ v2 = deltay*k+y0 - bl->y;
+ distance = v1*v1+v2*v2;
+ // triangular shooting range
+ if( distance <= range*k )
+ bl_list[bl_list_count++]=bl;
+ }
+ }
+ }//end for elements
+ }
+
+ if(type==0 || type==BL_MOB) {
+ bl = map[m].block_mob[bx+by*map[m].bxs]; // and the mob block
+ for(i=0;i<c2 && bl;i++,bl=bl->next){
+ if(bl && bl_list_count<BL_LIST_MAX) {
+ // calculate the perpendicular from block xy to the straight line
+ k = kfact*(deltax*bl->x + deltay*bl->y + knorm);
+//printf("mob: (%i,%i) k=%f ",bl->x,bl->y, k);
+ // check if the perpendicular is within start and end of our line
+ if(k>=0 && k<=1)
+ {
+ v1 = deltax*k+x0 - bl->x;
+ v2 = deltay*k+y0 - bl->y;
+ distance = v1*v1+v2*v2;
+//printf("dist: %f",distance);
+ // triangular shooting range
+ if( distance <= range*k )
+ {
+//printf(" hit");
+ bl_list[bl_list_count++]=bl;
+ }
+ }
+//printf("\n");
+ }
+ }//end for mobs
+ }
+ }//end for(bx,by)
+
+
+ if(bl_list_count>=BL_LIST_MAX) {
+ if(battle_config.error_log)
+ printf("map_foreachinarea: *WARNING* block count too many!\n");
+ }
+
+ va_start(ap,type);
+ map_freeblock_lock(); // ƒƒ‚ƒŠ‚©‚ç‚̉ð•ú‚ð‹ÖŽ~‚·‚é
+
+ for(i=blockcount;i<bl_list_count;i++)
+ if(bl_list[i]->prev) // —L?‚©‚Ç‚¤‚©ƒ`ƒFƒbƒN
+ func(bl_list[i],ap);
+
+ map_freeblock_unlock(); // ‰ð•ú‚ð‹–‰Â‚·‚é
+ va_end(ap);
+
+ bl_list_count = blockcount;
+
+*/
+
+
+//////////////////////////////////////////////////////////////
+//
+// sharp shooting 2
+//
+//////////////////////////////////////////////////////////////
+// problem:
+// finding targets standing exactly on a line
+// (only t1 and t2 get hit)
+//
+// target 1
+// x t4
+// t2
+// t3 x
+// x
+// S
+//////////////////////////////////////////////////////////////
+ va_list ap;
+ int i, blockcount = bl_list_count;
+ struct block_list *bl;
+ int c1,c2;
+
+ //////////////////////////////////////////////////////////////
+ // linear parametric equation
+ // x=(x1-x0)*t+x0; y=(y1-y0)*t+y0; t=[0,1]
+ //////////////////////////////////////////////////////////////
+ // linear equation for finding a single line between (x0,y0)->(x1,y1)
+ // independent of the given xy-values
+ double dx = 0.0;
+ double dy = 0.0;
+ int bx=-1; // initialize block coords to some impossible value
+ int by=-1;
+
+ int t;
+ ///////////////////////////////
+ // find maximum runindex
+ int tmax = abs(y1-y0);
+ if(tmax < abs(x1-x0))
+ tmax = abs(x1-x0);
+ // pre-calculate delta values for x and y destination
+ // should speed up cause you don't need to divide in the loop
+ if(tmax>0)
+ {
+ dx = ((double)(x1-x0)) / ((double)tmax);
+ dy = ((double)(y1-y0)) / ((double)tmax);
+ }
+ // go along the index
+ for(t=0; t<=tmax; t++)
+ { // xy-values of the line including start and end point
+ int x = (int)floor(dx * (double)t +0.5)+x0;
+ int y = (int)floor(dy * (double)t +0.5)+y0;
+
+ // check the block index of the calculated xy
+ if( (bx!=x/BLOCK_SIZE) || (by!=y/BLOCK_SIZE) )
+ { // we have reached a new block
+ // so we store the current block coordinates
+ bx = x/BLOCK_SIZE;
+ by = y/BLOCK_SIZE;
+
+ // and process the data
+ c1 = map[m].block_count[bx+by*map[m].bxs]; // number of elements in the block
+ c2 = map[m].block_mob_count[bx+by*map[m].bxs]; // number of mobs in the mob block
+ if( (c1==0) && (c2==0) ) continue; // skip if nothing in the block
+
+ if(type==0 || type!=BL_MOB) {
+ bl = map[m].block[bx+by*map[m].bxs]; // a block with the elements
+ for(i=0;i<c1 && bl;i++,bl=bl->next){ // go through all elements
+ if( bl && ( !type || bl->type==type ) && bl_list_count<BL_LIST_MAX )
+ {
+ // check if block xy is on the line
+ if( (bl->x-x0)*(y1-y0) == (bl->y-y0)*(x1-x0) )
+ // and if it is within start and end point
+ if( (((x0<=x1)&&(x0<=bl->x)&&(bl->x<=x1)) || ((x0>=x1)&&(x0>=bl->x)&&(bl->x>=x1))) &&
+ (((y0<=y1)&&(y0<=bl->y)&&(bl->y<=y1)) || ((y0>=y1)&&(y0>=bl->y)&&(bl->y>=y1))) )
+ bl_list[bl_list_count++]=bl;
+ }
+ }//end for elements
+ }
+
+ if(type==0 || type==BL_MOB) {
+ bl = map[m].block_mob[bx+by*map[m].bxs]; // and the mob block
+ for(i=0;i<c2 && bl;i++,bl=bl->next){
+ if(bl && bl_list_count<BL_LIST_MAX) {
+ // check if mob xy is on the line
+ if( (bl->x-x0)*(y1-y0) == (bl->y-y0)*(x1-x0) )
+ // and if it is within start and end point
+ if( (((x0<=x1)&&(x0<=bl->x)&&(bl->x<=x1)) || ((x0>=x1)&&(x0>=bl->x)&&(bl->x>=x1))) &&
+ (((y0<=y1)&&(y0<=bl->y)&&(bl->y<=y1)) || ((y0>=y1)&&(y0>=bl->y)&&(bl->y>=y1))) )
+ bl_list[bl_list_count++]=bl;
+ }
+ }//end for mobs
+ }
+ }
+ }//end for index
+
+ if(bl_list_count>=BL_LIST_MAX) {
+ if(battle_config.error_log)
+ printf("map_foreachinarea: *WARNING* block count too many!\n");
+ }
+
+ va_start(ap,type);
+ map_freeblock_lock(); // ƒƒ‚ƒŠ‚©‚ç‚̉ð•ú‚ð‹ÖŽ~‚·‚é
+
+ for(i=blockcount;i<bl_list_count;i++)
+ if(bl_list[i]->prev) // —L?‚©‚Ç‚¤‚©ƒ`ƒFƒbƒN
+ func(bl_list[i],ap);
+
+ map_freeblock_unlock(); // ‰ð•ú‚ð‹–‰Â‚·‚é
va_end(ap);
+
bl_list_count = blockcount;
}
/*==========================================
- * °ƒAƒCƒeƒ€‚âƒGƒtƒFƒNƒg—p‚̈ꎞobjŠ„‚è“–‚Ä
- * object[]‚ւ̕ۑ¶‚Æid_db“o˜^‚Ü‚Å
+ * °ƒAƒCƒeƒ€‚âƒGƒtƒFƒNƒg—p‚̈ꎞobjŠ„‚è?‚Ä
+ * object[]‚ւ̕ۑ¶‚Æid_db“o?‚Ü‚Å
*
* bl->id‚à‚±‚Ì’†‚Åݒ肵‚Ä–â‘è–³‚¢?
*------------------------------------------
@@ -627,7 +1131,7 @@ int map_addobject(struct block_list *bl) {
if(first_free_object_id<2 || first_free_object_id>=MAX_FLOORITEM)
first_free_object_id=2;
for(i=first_free_object_id;i<MAX_FLOORITEM;i++)
- if(object[i]==NULL)
+ if(objects[i]==NULL)
break;
if(i>=MAX_FLOORITEM){
if(battle_config.error_log)
@@ -637,29 +1141,29 @@ int map_addobject(struct block_list *bl) {
first_free_object_id=i;
if(last_object_id<i)
last_object_id=i;
- object[i]=bl;
+ objects[i]=bl;
numdb_insert(id_db,i,bl);
return i;
}
/*==========================================
* ˆêŽžobject‚̉ð•ú
- * map_delobject‚Ìfree‚µ‚È‚¢ƒo[ƒWƒ‡ƒ“
+ * map_delobject‚Ìfree‚µ‚È‚¢ƒo?ƒWƒ‡ƒ“
*------------------------------------------
*/
int map_delobjectnofree(int id) {
- if(object[id]==NULL)
+ if(objects[id]==NULL)
return 0;
- map_delblock(object[id]);
+ map_delblock(objects[id]);
numdb_erase(id_db,id);
-// map_freeblock(object[id]);
- object[id]=NULL;
+// map_freeblock(objects[id]);
+ objects[id]=NULL;
if(first_free_object_id>id)
first_free_object_id=id;
- while(last_object_id>2 && object[last_object_id]==NULL)
+ while(last_object_id>2 && objects[last_object_id]==NULL)
last_object_id--;
return 0;
@@ -670,11 +1174,11 @@ int map_delobjectnofree(int id) {
* block_list‚©‚ç‚ÌíœAid_db‚©‚ç‚Ìíœ
* object data‚ÌfreeAobject[]‚Ö‚ÌNULL‘ã“ü
*
- * add‚Ƃ̑ÎÌ«‚ª–³‚¢‚Ì‚ª‹C‚ɂȂé
+ * add‚Æ‚Ì??«‚ª–³‚¢‚Ì‚ª?‚ɂȂé
*------------------------------------------
*/
int map_delobject(int id) {
- struct block_list *obj = object[id];
+ struct block_list *obj = objects[id];
if(obj==NULL)
return 0;
@@ -693,20 +1197,20 @@ int map_delobject(int id) {
void map_foreachobject(int (*func)(struct block_list*,va_list),int type,...) {
int i;
int blockcount=bl_list_count;
- va_list ap=NULL;
+ va_list ap;
va_start(ap,type);
for(i=2;i<=last_object_id;i++){
- if(object[i]){
- if(type && object[i]->type!=type)
+ if(objects[i]){
+ if(type && objects[i]->type!=type)
continue;
if(bl_list_count>=BL_LIST_MAX) {
if(battle_config.error_log)
printf("map_foreachobject: too many block !\n");
}
else
- bl_list[bl_list_count++]=object[i];
+ bl_list[bl_list_count++]=objects[i];
}
}
@@ -729,13 +1233,13 @@ void map_foreachobject(int (*func)(struct block_list*,va_list),int type,...) {
* data!=0‚ÌŽž‚ÍE‚¤“™‚ÅÁ‚¦‚½Žž‚Æ‚µ‚Ä“®ì
*
* ŒãŽÒ‚ÍAmap_clearflooritem(id)‚Ö
- * map.h“à‚Å#define‚µ‚Ä‚ ‚é
+ * map.h?‚Å#define‚µ‚Ä‚ ‚é
*------------------------------------------
*/
int map_clearflooritem_timer(int tid,unsigned int tick,int id,int data) {
struct flooritem_data *fitem=NULL;
- fitem = (struct flooritem_data *)object[id];
+ fitem = (struct flooritem_data *)objects[id];
if(fitem==NULL || fitem->bl.type!=BL_ITEM || (!data && fitem->cleartimer != tid)){
if(battle_config.error_log)
printf("map_clearflooritem_timer : error\n");
@@ -752,14 +1256,14 @@ int map_clearflooritem_timer(int tid,unsigned int tick,int id,int data) {
}
/*==========================================
- * (m,x,y)‚ÌŽüˆÍrangeƒ}ƒX“à‚Ì‹ó‚«(=N“ü‰Â”\)cell‚Ì
- * “à‚©‚ç“K“–‚ȃ}ƒX–Ú‚ÌÀ•W‚ðx+(y<<16)‚ŕԂ·
+ * (m,x,y)‚ÌŽü?rangeƒ}ƒX?‚Ì‹ó‚«(=N“ü‰Â”\)cell‚Ì
+ * ?‚©‚ç“K?‚ȃ}ƒX–Ú‚ÌÀ•W‚ðx+(y<<16)‚ŕԂ·
*
- * Œ»órange=1‚ŃAƒCƒeƒ€ƒhƒƒbƒv—p“r‚Ì‚Ý
+ * Œ»?range=1‚ŃAƒCƒeƒ€ƒhƒƒbƒv—p“r‚Ì‚Ý
*------------------------------------------
*/
int map_searchrandfreecell(int m,int x,int y,int range) {
- int free_cell,i,j,c;
+ int free_cell,i,j;
for(free_cell=0,i=-range;i<=range;i++){
if(i+y<0 || i+y>=map[m].ys)
@@ -767,7 +1271,7 @@ int map_searchrandfreecell(int m,int x,int y,int range) {
for(j=-range;j<=range;j++){
if(j+x<0 || j+x>=map[m].xs)
continue;
- if((c=read_gat(m,j+x,i+y))==1 || c==5)
+ if(map_getcell(m,j+x,i+y,CELL_CHKNOPASS))
continue;
free_cell++;
}
@@ -781,7 +1285,7 @@ int map_searchrandfreecell(int m,int x,int y,int range) {
for(j=-range;j<=range;j++){
if(j+x<0 || j+x>=map[m].xs)
continue;
- if((c=read_gat(m,j+x,i+y))==1 || c==5)
+ if(map_getcell(m,j+x,i+y,CELL_CHKNOPASS))
continue;
if(free_cell==0){
x+=j;
@@ -797,7 +1301,7 @@ int map_searchrandfreecell(int m,int x,int y,int range) {
}
/*==========================================
- * (m,x,y)‚ð’†S‚É3x3ˆÈ“à‚ɰƒAƒCƒeƒ€Ý’u
+ * (m,x,y)‚ð’†S‚É3x3ˆÈ?‚ɰƒAƒCƒeƒ€Ý’u
*
* item_data‚ÍamountˆÈŠO‚ðcopy‚·‚é
*------------------------------------------
@@ -829,7 +1333,7 @@ int map_addflooritem(struct item *item_data,int amount,int m,int x,int y,struct
fitem->bl.id = map_addobject(&fitem->bl);
if(fitem->bl.id==0){
- free(fitem);
+ aFree(fitem);
return 0;
}
@@ -876,9 +1380,9 @@ void map_addchariddb(int charid, char *name) {
struct charid2nick *p=NULL;
int req=0;
- p=numdb_search(charid_db,charid);
- if(p==NULL){ // ƒf[ƒ^ƒx[ƒX‚ɂȂ¢
- p = (struct charid2nick *)aCalloc(1,sizeof(struct charid2nick));
+ p = (struct charid2nick*)numdb_search(charid_db,charid);
+ if(p==NULL){ // ƒf?ƒ^ƒx?ƒX‚ɂȂ¢
+ p = (struct charid2nick *)aCallocA(1,sizeof(struct charid2nick));
p->req_id=0;
}else
numdb_erase(charid_db,charid);
@@ -903,8 +1407,8 @@ int map_reqchariddb(struct map_session_data * sd,int charid) {
nullpo_retr(0, sd);
- p=numdb_search(charid_db,charid);
- if(p!=NULL) // ƒf[ƒ^ƒx[ƒX‚É‚·‚łɂ ‚é
+ p = (struct charid2nick*)numdb_search(charid_db,charid);
+ if(p!=NULL) // ƒf?ƒ^ƒx?ƒX‚É‚·‚łɂ ‚é
return 0;
p = (struct charid2nick *)aCalloc(1,sizeof(struct charid2nick));
p->req_id=sd->bl.id;
@@ -943,105 +1447,133 @@ void map_addnickdb(struct map_session_data *sd) {
}
/*==========================================
- * PC‚Ìquitˆ— map.c“à•ª
+ * PC‚Ìquit?— map.c?•ª
*
- * quitˆ—‚ÌŽå‘Ì‚ªˆá‚¤‚悤‚È‹C‚à‚µ‚Ä‚«‚½
+ * quit?—‚ÌŽå?‚ªˆá‚¤‚悤‚È?‚à‚µ‚Ä‚«‚½
*------------------------------------------
*/
int map_quit(struct map_session_data *sd) {
- int i;
-
nullpo_retr(0, sd);
- if(sd->chatID) // ƒ`ƒƒƒbƒg‚©‚ço‚é
- chat_leavechat(sd);
+ if(!sd->state.waitingdisconnect) {
+ if (sd->state.event_disconnect) {
+ if (script_config.event_script_type == 0) {
+ struct npc_data *npc;
+ if ((npc = npc_name2id(script_config.logout_event_name))) {
+ run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCLogoutNPC
+ sprintf (tmp_output, "Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.logout_event_name);
+ ShowStatus(tmp_output);
+ }
+ } else {
+ sprintf (tmp_output, "%d '"CL_WHITE"%s"CL_RESET"' events executed.\n",
+ npc_event_doall_id(script_config.logout_event_name, sd->bl.id), script_config.logout_event_name);
+ ShowStatus(tmp_output);
+ }
+ }
- if(sd->trade_partner) // Žæˆø‚ð’†’f‚·‚é
- trade_tradecancel(sd);
+ if(sd->chatID) // ƒ`ƒƒƒbƒg‚©‚ço‚é
+ chat_leavechat(sd);
- if(sd->party_invite>0) // ƒp[ƒeƒBŠ©—U‚ð‹‘”Û‚·‚é
- party_reply_invite(sd,sd->party_invite_account,0);
+ if(sd->trade_partner) // Žæˆø‚ð’†?‚·‚é
+ trade_tradecancel(sd);
- if(sd->guild_invite>0) // ƒMƒ‹ƒhŠ©—U‚ð‹‘”Û‚·‚é
- guild_reply_invite(sd,sd->guild_invite,0);
- if(sd->guild_alliance>0) // ƒMƒ‹ƒh“¯–¿Š©—U‚ð‹‘”Û‚·‚é
- guild_reply_reqalliance(sd,sd->guild_alliance_account,0);
+ if(sd->party_invite>0) // ƒp?ƒeƒB?—U‚ð‹‘”Û‚·‚é
+ party_reply_invite(sd,sd->party_invite_account,0);
- party_send_logout(sd); // ƒp[ƒeƒB‚̃ƒOƒAƒEƒgƒƒbƒZ[ƒW‘—M
+ if(sd->guild_invite>0) // ƒMƒ‹ƒh?—U‚ð‹‘”Û‚·‚é
+ guild_reply_invite(sd,sd->guild_invite,0);
+ if(sd->guild_alliance>0) // ƒMƒ‹ƒh“¯–¿?—U‚ð‹‘”Û‚·‚é
+ guild_reply_reqalliance(sd,sd->guild_alliance_account,0);
- guild_send_memberinfoshort(sd,0); // ƒMƒ‹ƒh‚̃ƒOƒAƒEƒgƒƒbƒZ[ƒW‘—M
+ party_send_logout(sd); // ƒp?ƒeƒB‚̃ƒOƒAƒEƒgƒƒbƒZ?ƒW‘—M
- pc_cleareventtimer(sd); // ƒCƒxƒ“ƒgƒ^ƒCƒ}‚ð”jŠü‚·‚é
+ guild_send_memberinfoshort(sd,0); // ƒMƒ‹ƒh‚̃ƒOƒAƒEƒgƒƒbƒZ?ƒW‘—M
- if(sd->state.storage_flag)
- storage_guild_storage_quit(sd,0);
- else
- storage_storage_quit(sd); // ‘qŒÉ‚ðŠJ‚¢‚Ä‚é‚È‚ç•Û‘¶‚·‚é
-
- skill_castcancel(&sd->bl,0); // ‰r¥‚ð’†’f‚·‚é
- skill_stop_dancing(&sd->bl,1);// ƒ_ƒ“ƒX/‰‰‘t’†’f
-
- if(sd->sc_data && sd->sc_data[SC_BERSERK].timer!=-1) //ƒo[ƒT[ƒN’†‚ÌI—¹‚ÍHP‚ð100‚É
- sd->status.hp = 100;
-
- skill_status_change_clear(&sd->bl,1); // ƒXƒe[ƒ^ƒXˆÙí‚ð‰ðœ‚·‚é
- skill_clear_unitgroup(&sd->bl); // ƒXƒLƒ‹ƒ†ƒjƒbƒgƒOƒ‹[ƒv‚Ìíœ
- skill_cleartimerskill(&sd->bl);
- pc_stop_walking(sd,0);
- pc_stopattack(sd);
- pc_delinvincibletimer(sd);
- pc_delspiritball(sd,sd->spiritball,1);
- skill_gangsterparadise(sd,0);
-
- pc_calcstatus(sd,4);
-
- clif_clearchar_area(&sd->bl,2);
-
- if(sd->status.pet_id && sd->pd) {
- pet_lootitem_drop(sd->pd,sd);
- pet_remove_map(sd);
- if(sd->pet.intimate <= 0) {
- intif_delete_petdata(sd->status.pet_id);
- sd->status.pet_id = 0;
- sd->pd = NULL;
- sd->petDB = NULL;
- }
+ pc_cleareventtimer(sd); // ƒCƒxƒ“ƒgƒ^ƒCƒ}‚ð”jŠü‚·‚é
+
+ if(sd->state.storage_flag)
+ storage_guild_storage_quit(sd,0);
else
- intif_save_petdata(sd->status.account_id,&sd->pet);
- }
-
- if(pc_isdead(sd))
- pc_setrestartvalue(sd,2);
- pc_makesavestatus(sd);
- //ƒNƒ[ƒ“ƒXƒLƒ‹‚ÅŠo‚¦‚½ƒXƒLƒ‹‚ÍÁ‚·
- for(i=0;i<MAX_SKILL;i++){
- if(sd->status.skill[i].flag == 13){
- sd->status.skill[i].id=0;
- sd->status.skill[i].lv=0;
- sd->status.skill[i].flag=0;
+ storage_storage_quit(sd); // ‘qŒÉ‚ðŠJ‚¢‚Ä‚é‚È‚ç•Û‘¶‚·‚é
+
+ // check if we've been authenticated [celest]
+ if (sd->state.auth)
+ skill_castcancel(&sd->bl,0); // ‰r¥‚ð’†?‚·‚é
+
+ skill_stop_dancing(&sd->bl,1);// ƒ_ƒ“ƒX/‰‰‘t’†?
+
+ if(sd->sc_data && sd->sc_data[SC_BERSERK].timer!=-1) //ƒo?ƒT?ƒN’†‚ÌI—¹‚ÍHP‚ð100‚É
+ sd->status.hp = 100;
+
+ status_change_clear(&sd->bl,1); // ƒXƒe?ƒ^ƒXˆÙí‚ð‰ðœ‚·‚é
+ skill_clear_unitgroup(&sd->bl); // ƒXƒLƒ‹ƒ†ƒjƒbƒgƒOƒ‹?ƒv‚Ìíœ
+ skill_cleartimerskill(&sd->bl);
+
+ // check if we've been authenticated [celest]
+ if (sd->state.auth) {
+ pc_stop_walking(sd,0);
+ pc_stopattack(sd);
+ pc_delinvincibletimer(sd);
+ }
+ pc_delspiritball(sd,sd->spiritball,1);
+ skill_gangsterparadise(sd,0);
+ skill_unit_move(&sd->bl,gettick(),0);
+
+ if (sd->state.auth)
+ status_calc_pc(sd,4);
+ // skill_clear_unitgroup(&sd->bl); // [Sara-chan]
+
+ clif_clearchar_area(&sd->bl,2);
+
+ if(sd->status.pet_id && sd->pd) {
+ pet_lootitem_drop(sd->pd,sd);
+ pet_remove_map(sd);
+ if(sd->pet.intimate <= 0) {
+ intif_delete_petdata(sd->status.pet_id);
+ sd->status.pet_id = 0;
+ sd->pd = NULL;
+ sd->petDB = NULL;
+ }
+ else
+ intif_save_petdata(sd->status.account_id,&sd->pet);
}
- }
- chrif_save(sd);
- storage_storage_save(sd);
- if( sd->npc_stackbuf && sd->npc_stackbuf != NULL)
- free( sd->npc_stackbuf );
+ if(pc_isdead(sd))
+ pc_setrestartvalue(sd,2);
- map_delblock(&sd->bl);
+ pc_clean_skilltree(sd);
+ pc_makesavestatus(sd);
+ chrif_save(sd);
+ storage_storage_dirty(sd);
+ storage_storage_save(sd);
+ map_delblock(&sd->bl);
+ }
+
+ if( sd->npc_stackbuf && sd->npc_stackbuf != NULL) {
+ aFree( sd->npc_stackbuf );
+ sd->npc_stackbuf = NULL;
+ }
-#ifndef TXT_ONLY
chrif_char_offline(sd);
-#endif
- numdb_erase(id_db,sd->bl.id);
+ {
+ void *p = numdb_search(charid_db,sd->status.char_id);
+ if(p) {
+ numdb_erase(charid_db,sd->status.char_id);
+ aFree(p);
+ }
+ }
strdb_erase(nick_db,sd->status.name);
numdb_erase(charid_db,sd->status.char_id);
+ numdb_erase(id_db,sd->bl.id);
+ aFree(sd->reg);
+ aFree(sd->regstr);
return 0;
}
/*==========================================
- * id”Ô†‚ÌPC‚ð’T‚·B‹‚È‚¯‚ê‚ÎNULL
+ * id”Ô?‚ÌPC‚ð’T‚·B‹‚È‚¯‚ê‚ÎNULL
*------------------------------------------
*/
struct map_session_data * map_id2sd(int id) {
@@ -1060,21 +1592,23 @@ struct map_session_data * map_id2sd(int id) {
return NULL;
*/
int i;
- struct map_session_data *sd=NULL;
+ struct map_session_data *sd;
+
+ if (id <= 0) return 0;
for(i = 0; i < fd_max; i++)
- if (session[i] && (sd = session[i]->session_data) && sd->bl.id == id)
+ if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) && sd->bl.id == id)
return sd;
return NULL;
}
/*==========================================
- * char_id”Ô†‚Ì–¼‘O‚ð’T‚·
+ * char_id”Ô?‚Ì–¼‘O‚ð’T‚·
*------------------------------------------
*/
char * map_charid2nick(int id) {
- struct charid2nick *p=numdb_search(charid_db,id);
+ struct charid2nick *p = (struct charid2nick*)numdb_search(charid_db,id);
if(p==NULL)
return NULL;
@@ -1083,6 +1617,18 @@ char * map_charid2nick(int id) {
return p->nick;
}
+struct map_session_data * map_charid2sd(int id) {
+ int i;
+ struct map_session_data *sd;
+
+ if (id <= 0) return 0;
+
+ for(i = 0; i < fd_max; i++)
+ if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) && sd->status.char_id == id)
+ return sd;
+
+ return NULL;
+}
/*==========================================
* Search session data from a nick name
@@ -1101,7 +1647,7 @@ struct map_session_data * map_nick2sd(char *nick) {
nicklen = strlen(nick);
for (i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth)
+ if (session[i] && (pl_sd = (struct map_session_data*)session[i]->session_data) && pl_sd->state.auth)
// Without case sensitive check (increase the number of similar character names found)
if (strnicmp(pl_sd->status.name, nick, nicklen) == 0) {
// Strict comparison (if found, we finish the function immediatly with correct value)
@@ -1121,27 +1667,27 @@ struct map_session_data * map_nick2sd(char *nick) {
}
/*==========================================
- * id”Ô†‚Ì•¨‚ð’T‚·
+ * id”Ô?‚Ì•¨‚ð’T‚·
* ˆêŽžobject‚Ìꇂ͔z—ñ‚ðˆø‚­‚Ì‚Ý
*------------------------------------------
*/
struct block_list * map_id2bl(int id)
{
struct block_list *bl=NULL;
- if(id<sizeof(object)/sizeof(object[0]))
- bl = object[id];
+ if(id >= 0 && id < sizeof(objects)/sizeof(objects[0]))
+ bl = objects[id];
else
- bl = numdb_search(id_db,id);
+ bl = (struct block_list*)numdb_search(id_db,id);
return bl;
}
/*==========================================
- * id_db“à‚Ì‘S‚Ä‚Éfunc‚ðŽÀs
+ * id_db?‚Ì‘S‚Ä‚Éfunc‚ð?s
*------------------------------------------
*/
int map_foreachiddb(int (*func)(void*,void*,va_list),...) {
- va_list ap=NULL;
+ va_list ap;
va_start(ap,func);
numdb_foreach(id_db,func,ap);
@@ -1179,48 +1725,60 @@ int map_addnpc(int m,struct npc_data *nd) {
}
void map_removenpc(void) {
- int i,m,n=0;
-
- for(m=0;m<map_num;m++) {
- for(i=0;i<map[m].npc_num && i<MAX_NPC_PER_MAP;i++) {
- if(map[m].npc[i]!=NULL) {
- clif_clearchar_area(&map[m].npc[i]->bl,2);
- map_delblock(&map[m].npc[i]->bl);
- numdb_erase(id_db,map[m].npc[i]->bl.id);
- if(map[m].npc[i]->bl.subtype==SCRIPT) {
-// free(map[m].npc[i]->u.scr.script);
-// free(map[m].npc[i]->u.scr.label_list);
- }
- free(map[m].npc[i]);
- map[m].npc[i] = NULL;
- n++;
- }
- }
- }
- printf("%d NPCs removed.\n",n);
+ int i,m,n=0;
+
+ for(m=0;m<map_num;m++) {
+ for(i=0;i<map[m].npc_num && i<MAX_NPC_PER_MAP;i++) {
+ if(map[m].npc[i]!=NULL) {
+ clif_clearchar_area(&map[m].npc[i]->bl,2);
+ map_delblock(&map[m].npc[i]->bl);
+ numdb_erase(id_db,map[m].npc[i]->bl.id);
+ if(map[m].npc[i]->bl.subtype==SCRIPT) {
+ aFree(map[m].npc[i]->u.scr.script);
+ aFree(map[m].npc[i]->u.scr.label_list);
+ }
+ aFree(map[m].npc[i]);
+ map[m].npc[i] = NULL;
+ n++;
+ }
+ }
+ }
+
+ sprintf(tmp_output,"Successfully removed and freed from memory '"CL_WHITE"%d"CL_RESET"' NPCs.\n",n);
+ ShowStatus(tmp_output);
}
/*==========================================
- * map–¼‚©‚çmap”Ô†‚Ö•ÏŠ·
+ * map–¼‚©‚çmap”Ô?‚Ö?Š·
*------------------------------------------
*/
int map_mapname2mapid(char *name) {
struct map_data *md=NULL;
- md=strdb_search(map_db,name);
+ md = (struct map_data*)strdb_search(map_db,name);
+
+#ifdef USE_AFM
+ // If we can't find the .gat map try .afm instead [celest]
+ if(md==NULL && strstr(name,".gat")) {
+ char *afm_name = strdup(name);
+ strcpy(&afm_name[strlen(name) - 3], "afm");
+ md = (struct map_data*)strdb_search(map_db,afm_name);
+ }
+#endif
+
if(md==NULL || md->gat==NULL)
return -1;
return md->m;
}
/*==========================================
- * ‘¼ŽImap–¼‚©‚çip,port•ÏŠ·
+ * ‘¼ŽImap–¼‚©‚çip,port?Š·
*------------------------------------------
*/
int map_mapname2ipport(char *name,int *ip,int *port) {
struct map_data_other_server *mdos=NULL;
- mdos=strdb_search(map_db,name);
+ mdos = (struct map_data_other_server*)strdb_search(map_db,name);
if(mdos==NULL || mdos->gat)
return -1;
*ip=mdos->ip;
@@ -1311,20 +1869,74 @@ int map_calc_dir( struct block_list *src,int x,int y) {
* (m,x,y)‚Ìó‘Ԃ𒲂ׂé
*------------------------------------------
*/
-int map_getcell(int m,int x,int y) {
- if(x<0 || x>=map[m].xs-1 || y<0 || y>=map[m].ys-1)
- return 1;
- return map[m].gat[x+y*map[m].xs];
+
+int map_getcell(int m,int x,int y,cell_t cellchk)
+{
+ return (m < 0 || m > MAX_MAP_PER_SERVER) ? 0 : map_getcellp(&map[m],x,y,cellchk);
+}
+
+int map_getcellp(struct map_data* m,int x,int y,cell_t cellchk)
+{
+ int type;
+ nullpo_ret(m);
+
+ if(x<0 || x>=m->xs-1 || y<0 || y>=m->ys-1)
+ {
+ if(cellchk==CELL_CHKNOPASS) return 1;
+ return 0;
+ }
+ type = m->gat[x+y*m->xs];
+ if (cellchk<0x10)
+ type &= CELL_MASK;
+
+ switch(cellchk)
+ {
+ case CELL_CHKPASS:
+ return (type!=1 && type!=5);
+ case CELL_CHKNOPASS:
+ return (type==1 || type==5);
+ case CELL_CHKWALL:
+ return (type==1);
+ case CELL_CHKWATER:
+ return (type==3);
+ case CELL_CHKGROUND:
+ return (type==5);
+ case CELL_GETTYPE:
+ return type;
+ case CELL_CHKNPC:
+ return (type&CELL_NPC);
+ case CELL_CHKBASILICA:
+ return (type&CELL_BASILICA);
+ default:
+ return 0;
+ }
}
/*==========================================
- * (m,x,y)‚Ìó‘Ô‚ðt‚É‚·‚é
+ * (m,x,y)‚Ìó‘Ô‚ðÝ’è‚·‚é
*------------------------------------------
*/
-int map_setcell(int m,int x,int y,int t) {
+void map_setcell(int m,int x,int y,int cell)
+{
+ int j;
if(x<0 || x>=map[m].xs || y<0 || y>=map[m].ys)
- return t;
- return map[m].gat[x+y*map[m].xs]=t;
+ return;
+ j=x+y*map[m].xs;
+
+ switch (cell) {
+ case CELL_SETNPC:
+ map[m].gat[j] |= CELL_NPC;
+ break;
+ case CELL_SETBASILICA:
+ map[m].gat[j] |= CELL_BASILICA;
+ break;
+ case CELL_CLRBASILICA:
+ map[m].gat[j] &= ~CELL_BASILICA;
+ break;
+ default:
+ map[m].gat[j] = (map[m].gat[j]&~CELL_MASK) + cell;
+ break;
+ }
}
/*==========================================
@@ -1335,22 +1947,46 @@ int map_setipport(char *name,unsigned long ip,int port) {
struct map_data *md=NULL;
struct map_data_other_server *mdos=NULL;
- md=strdb_search(map_db,name);
+ md = (struct map_data*)strdb_search(map_db,name);
if(md==NULL){ // not exist -> add new data
mdos=(struct map_data_other_server *)aCalloc(1,sizeof(struct map_data_other_server));
memcpy(mdos->name,name,24);
mdos->gat = NULL;
mdos->ip = ip;
mdos->port = port;
+ mdos->map = NULL;
strdb_insert(map_db,mdos->name,mdos);
+ } else if(md->gat){
+ if(ip!=clif_getip() || port!=clif_getport()){
+ // “ǂݞ‚ñ‚Å‚¢‚½‚¯‚ÇA’S“–ŠO‚ɂȂÁ‚½ƒ}ƒbƒv
+ mdos=(struct map_data_other_server *)aCalloc(1,sizeof(struct map_data_other_server));
+ memcpy(mdos->name,name,24);
+ mdos->gat = NULL;
+ mdos->ip = ip;
+ mdos->port = port;
+ mdos->map = md;
+ strdb_insert(map_db,mdos->name,mdos);
+ // printf("from char server : %s -> %08lx:%d\n",name,ip,port);
+ } else {
+ // “ǂݞ‚ñ‚Å‚¢‚ÄA’S“–‚ɂȂÁ‚½ƒ}ƒbƒvi‰½‚à‚µ‚È‚¢j
+ ;
+ }
} else {
- if(md->gat){ // local -> check data
- if(ip!=clif_getip() || port!=clif_getport()){
- printf("from char server : %s -> %08lx:%d\n",name,ip,port);
- return 1;
+ mdos=(struct map_data_other_server *)md;
+ if(ip == clif_getip() && port == clif_getport()) {
+ // Ž©•ª‚Ì’S“–‚ɂȂÁ‚½ƒ}ƒbƒv
+ if(mdos->map == NULL) {
+ // “ǂݞ‚ñ‚Å‚¢‚È‚¢‚Ì‚ÅI—¹‚·‚é
+ printf("map_setipport : %s is not loaded.\n",name);
+ exit(1);
+ } else {
+ // “ǂݞ‚ñ‚Å‚¢‚é‚̂Œu‚«Š·‚¦‚é
+ md = mdos->map;
+ aFree(mdos);
+ strdb_insert(map_db,md->name,md);
}
- } else { // update
- mdos=(struct map_data_other_server *)md;
+ } else {
+ // ‘¼‚ÌŽI‚Ì’S“–ƒ}ƒbƒv‚Ȃ̂Œu‚«Š·‚¦‚邾‚¯
mdos->ip = ip;
mdos->port = port;
}
@@ -1358,12 +1994,62 @@ int map_setipport(char *name,unsigned long ip,int port) {
return 0;
}
+/*==========================================
+ * ‘¼ŽIŠÇ—‚̃}ƒbƒv‚ð‘S‚Äíœ
+ *------------------------------------------
+ */
+int map_eraseallipport_sub(void *key,void *data,va_list va) {
+ struct map_data_other_server *mdos = (struct map_data_other_server*)data;
+ if(mdos->gat == NULL && mdos->map == NULL) {
+ strdb_erase(map_db,key);
+ aFree(mdos);
+ }
+ return 0;
+}
+
+int map_eraseallipport(void) {
+ strdb_foreach(map_db,map_eraseallipport_sub);
+ return 1;
+}
+
+/*==========================================
+ * ‘¼ŽIŠÇ—‚̃}ƒbƒv‚ðdb‚©‚çíœ
+ *------------------------------------------
+ */
+int map_eraseipport(char *name,unsigned long ip,int port)
+{
+ struct map_data *md;
+ struct map_data_other_server *mdos;
+// unsigned char *p=(unsigned char *)&ip;
+
+ md=(struct map_data *) strdb_search(map_db,name);
+ if(md){
+ if(md->gat) // local -> check data
+ return 0;
+ else {
+ mdos=(struct map_data_other_server *)md;
+ if(mdos->ip==ip && mdos->port == port) {
+ if(mdos->map) {
+ // ‚±‚̃}ƒbƒvŽI‚Å‚à“ǂݞ‚ñ‚Å‚¢‚é‚̂ňړ®‚Å‚«‚é
+ return 1; // ŒÄ‚Ño‚µŒ³‚Å chrif_sendmap() ‚ð‚·‚é
+ } else {
+ strdb_erase(map_db,name);
+ aFree(mdos);
+ }
+// if(battle_config.etc_log)
+// printf("erase map %s %d.%d.%d.%d:%d\n",name,p[0],p[1],p[2],p[3],port);
+ }
+ }
+ }
+ return 0;
+}
+
// ‰Šú‰»Žü‚è
/*==========================================
* …ê‚‚³Ý’è
*------------------------------------------
*/
-static struct {
+static struct waterlist_ {
char mapname[24];
int waterheight;
} *waterlist=NULL;
@@ -1391,7 +2077,7 @@ static void map_readwater(char *watertxt) {
return;
}
if(waterlist==NULL)
- waterlist=aCalloc(MAX_MAP_PER_SERVER,sizeof(*waterlist));
+ waterlist = (struct waterlist_*)aCallocA(MAX_MAP_PER_SERVER,sizeof(*waterlist));
while(fgets(line,1020,fp) && n < MAX_MAP_PER_SERVER){
int wh,count;
if(line[0] == '/' && line[1] == '/')
@@ -1408,8 +2094,244 @@ static void map_readwater(char *watertxt) {
}
fclose(fp);
}
+/*==========================================
+* ƒ}ƒbƒvƒLƒƒƒbƒVƒ…‚ɒljÁ‚·‚é
+*===========================================*/
+
+// ƒ}ƒbƒvƒLƒƒƒbƒVƒ…‚ÌÅ‘å’l
+#define MAX_MAP_CACHE 768
+
+//Šeƒ}ƒbƒv‚²‚Æ‚ÌŬŒÀî•ñ‚ð“ü‚ê‚é‚à‚ÌAREAD_FROM_BITMAP—p
+struct map_cache_info {
+ char fn[32];//ƒtƒ@ƒCƒ‹–¼
+ int xs,ys; //•‚Æ‚‚³
+ int water_height;
+ int pos; // ƒf[ƒ^‚ª“ü‚ê‚Ä‚ ‚éêŠ
+ int compressed; // zilb’Ê‚¹‚邿‚¤‚É‚·‚éˆ×‚Ì—\–ñ
+ int compressed_len; // zilb’Ê‚¹‚邿‚¤‚É‚·‚éˆ×‚Ì—\–ñ
+}; // 56 byte
+
+struct map_cache_head {
+ int sizeof_header;
+ int sizeof_map;
+ // ã‚Ì‚Q‚‰ü•Ï•s‰Â
+ int nmaps; // ƒ}ƒbƒv‚̌”
+ int filesize;
+};
+
+struct {
+ struct map_cache_head head;
+ struct map_cache_info *map;
+ FILE *fp;
+ int dirty;
+} map_cache;
+
+static int map_cache_open(char *fn);
+static void map_cache_close(void);
+static int map_cache_read(struct map_data *m);
+static int map_cache_write(struct map_data *m);
+
+static int map_cache_open(char *fn)
+{
+ atexit(map_cache_close);
+ if(map_cache.fp) {
+ map_cache_close();
+ }
+ map_cache.fp = fopen(fn,"r+b");
+ if(map_cache.fp) {
+ fread(&map_cache.head,1,sizeof(struct map_cache_head),map_cache.fp);
+ fseek(map_cache.fp,0,SEEK_END);
+ if(
+ map_cache.head.sizeof_header == sizeof(struct map_cache_head) &&
+ map_cache.head.sizeof_map == sizeof(struct map_cache_info) &&
+ map_cache.head.nmaps == MAX_MAP_CACHE &&
+ map_cache.head.filesize == ftell(map_cache.fp)
+ ) {
+ // ƒLƒƒƒbƒVƒ…“ǂݞ‚ݬŒ÷
+ map_cache.map = (struct map_cache_info *) aMalloc(sizeof(struct map_cache_info) * map_cache.head.nmaps);
+ fseek(map_cache.fp,sizeof(struct map_cache_head),SEEK_SET);
+ fread(map_cache.map,sizeof(struct map_cache_info),map_cache.head.nmaps,map_cache.fp);
+ return 1;
+ }
+ fclose(map_cache.fp);
+ }
+ // “ǂݞ‚݂Ɏ¸”s‚µ‚½‚Ì‚ÅV‹K‚É쬂·‚é
+ map_cache.fp = fopen(fn,"wb");
+ if(map_cache.fp) {
+ memset(&map_cache.head,0,sizeof(struct map_cache_head));
+ map_cache.map = (struct map_cache_info *) aCalloc(sizeof(struct map_cache_info),MAX_MAP_CACHE);
+ map_cache.head.nmaps = MAX_MAP_CACHE;
+ map_cache.head.sizeof_header = sizeof(struct map_cache_head);
+ map_cache.head.sizeof_map = sizeof(struct map_cache_info);
+
+ map_cache.head.filesize = sizeof(struct map_cache_head);
+ map_cache.head.filesize += sizeof(struct map_cache_info) * map_cache.head.nmaps;
+
+ map_cache.dirty = 1;
+ return 1;
+ }
+ return 0;
+}
+
+static void map_cache_close(void)
+{
+ if(!map_cache.fp) { return; }
+ if(map_cache.dirty) {
+ fseek(map_cache.fp,0,SEEK_SET);
+ fwrite(&map_cache.head,1,sizeof(struct map_cache_head),map_cache.fp);
+ fwrite(map_cache.map,map_cache.head.nmaps,sizeof(struct map_cache_info),map_cache.fp);
+ }
+ fclose(map_cache.fp);
+ aFree(map_cache.map);
+ map_cache.fp = NULL;
+ return;
+}
+
+int map_cache_read(struct map_data *m)
+{
+ int i;
+ if(!map_cache.fp) { return 0; }
+ for(i = 0;i < map_cache.head.nmaps ; i++) {
+ if(!strcmp(m->name,map_cache.map[i].fn)) {
+ if(map_cache.map[i].water_height != map_waterheight(m->name)) {
+ // …ê‚Ì‚‚³‚ªˆá‚¤‚̂œǂݒ¼‚µ
+ return 0;
+ } else if(map_cache.map[i].compressed == 0) {
+ // ”ñˆ³kƒtƒ@ƒCƒ‹
+ int size = map_cache.map[i].xs * map_cache.map[i].ys;
+ m->xs = map_cache.map[i].xs;
+ m->ys = map_cache.map[i].ys;
+ m->gat = (unsigned char *)aCalloc(m->xs * m->ys,sizeof(unsigned char));
+ fseek(map_cache.fp,map_cache.map[i].pos,SEEK_SET);
+ if(fread(m->gat,1,size,map_cache.fp) == size) {
+ // ¬Œ÷
+ return 1;
+ } else {
+ // ‚È‚º‚©ƒtƒ@ƒCƒ‹Œã”¼‚ªŒ‡‚¯‚Ä‚é‚̂œǂݒ¼‚µ
+ m->xs = 0; m->ys = 0; m->gat = NULL; aFree(m->gat);
+ return 0;
+ }
+ } else if(map_cache.map[i].compressed == 1) {
+ // ˆ³kƒtƒ‰ƒO=1 : zlib
+ unsigned char *buf;
+ unsigned long dest_len;
+ int size_compress = map_cache.map[i].compressed_len;
+ m->xs = map_cache.map[i].xs;
+ m->ys = map_cache.map[i].ys;
+ m->gat = (unsigned char *)aMalloc(m->xs * m->ys * sizeof(unsigned char));
+ buf = (unsigned char*)aMalloc(size_compress);
+ fseek(map_cache.fp,map_cache.map[i].pos,SEEK_SET);
+ if(fread(buf,1,size_compress,map_cache.fp) != size_compress) {
+ // ‚È‚º‚©ƒtƒ@ƒCƒ‹Œã”¼‚ªŒ‡‚¯‚Ä‚é‚̂œǂݒ¼‚µ
+ printf("fread error\n");
+ aFree(m->gat); m->xs = 0; m->ys = 0; m->gat = NULL;
+ aFree(buf);
+ return 0;
+ }
+ dest_len = m->xs * m->ys;
+ decode_zip(m->gat,&dest_len,buf,size_compress);
+ if(dest_len != map_cache.map[i].xs * map_cache.map[i].ys) {
+ // ³í‚ɉ𓀂ªo—ˆ‚ĂȂ¢
+ aFree(m->gat); m->xs = 0; m->ys = 0; m->gat = NULL;
+ aFree(buf);
+ return 0;
+ }
+ aFree(buf);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+static int map_cache_write(struct map_data *m)
+{
+ int i;
+ unsigned long len_new , len_old;
+ char *write_buf;
+ if(!map_cache.fp) { return 0; }
+ for(i = 0;i < map_cache.head.nmaps ; i++) {
+ if(!strcmp(m->name,map_cache.map[i].fn)) {
+ // “¯‚¶ƒGƒ“ƒgƒŠ[‚ª‚ ‚ê‚Îã‘‚«
+ if(map_cache.map[i].compressed == 0) {
+ len_old = map_cache.map[i].xs * map_cache.map[i].ys;
+ } else if(map_cache.map[i].compressed == 1) {
+ len_old = map_cache.map[i].compressed_len;
+ } else {
+ // ƒTƒ|[ƒg‚³‚ê‚ĂȂ¢Œ`Ž®‚Ȃ̂Œ·‚³‚O
+ len_old = 0;
+ }
+ if(map_read_flag == 2) {
+ // ˆ³k•Û‘¶
+ // ‚³‚·‚ª‚É‚Q”{‚É–c‚ê‚鎖‚͂Ȃ¢‚Æ‚¢‚¤Ž–‚Å
+ write_buf = (char *) aMalloc(m->xs * m->ys * 2);
+ len_new = m->xs * m->ys * 2;
+ encode_zip((unsigned char *) write_buf,&len_new,m->gat,m->xs * m->ys);
+ map_cache.map[i].compressed = 1;
+ map_cache.map[i].compressed_len = len_new;
+ } else {
+ len_new = m->xs * m->ys;
+ write_buf = (char *) m->gat;
+ map_cache.map[i].compressed = 0;
+ map_cache.map[i].compressed_len = 0;
+ }
+ if(len_new <= len_old) {
+ // ƒTƒCƒY‚ª“¯‚¶‚©¬‚³‚­‚È‚Á‚½‚Ì‚Åꊂ͕ςí‚ç‚È‚¢
+ fseek(map_cache.fp,map_cache.map[i].pos,SEEK_SET);
+ fwrite(write_buf,1,len_new,map_cache.fp);
+ } else {
+ // V‚µ‚¢êЂɓo˜^
+ fseek(map_cache.fp,map_cache.head.filesize,SEEK_SET);
+ fwrite(write_buf,1,len_new,map_cache.fp);
+ map_cache.map[i].pos = map_cache.head.filesize;
+ map_cache.head.filesize += len_new;
+ }
+ map_cache.map[i].xs = m->xs;
+ map_cache.map[i].ys = m->ys;
+ map_cache.map[i].water_height = map_waterheight(m->name);
+ map_cache.dirty = 1;
+ if(map_read_flag == 2) {
+ aFree(write_buf);
+ }
+ return 0;
+ }
+ }
+ // “¯‚¶ƒGƒ“ƒgƒŠ‚ª–³‚¯‚ê‚Α‚«ž‚ß‚éꊂð’T‚·
+ for(i = 0;i < map_cache.head.nmaps ; i++) {
+ if(map_cache.map[i].fn[0] == 0) {
+ // V‚µ‚¢êЂɓo˜^
+ if(map_read_flag == 2) {
+ write_buf = (char *) aMalloc(m->xs * m->ys * 2);
+ len_new = m->xs * m->ys * 2;
+ encode_zip((unsigned char *) write_buf,&len_new,m->gat,m->xs * m->ys);
+ map_cache.map[i].compressed = 1;
+ map_cache.map[i].compressed_len = len_new;
+ } else {
+ len_new = m->xs * m->ys;
+ write_buf = (char *) m->gat;
+ map_cache.map[i].compressed = 0;
+ map_cache.map[i].compressed_len = 0;
+ }
+ strncpy(map_cache.map[i].fn,m->name,sizeof(map_cache.map[0].fn));
+ fseek(map_cache.fp,map_cache.head.filesize,SEEK_SET);
+ fwrite(write_buf,1,len_new,map_cache.fp);
+ map_cache.map[i].pos = map_cache.head.filesize;
+ map_cache.map[i].xs = m->xs;
+ map_cache.map[i].ys = m->ys;
+ map_cache.map[i].water_height = map_waterheight(m->name);
+ map_cache.head.filesize += len_new;
+ map_cache.dirty = 1;
+ if(map_read_flag == 2) {
+ aFree(write_buf);
+ }
+ return 0;
+ }
+ }
+ // ‘‚«ž‚߂Ȃ©‚Á‚½
+ return 1;
+}
+#ifdef USE_AFM
static int map_readafm(int m,char *fn) {
/*
@@ -1474,7 +2396,7 @@ static int map_readafm(int m,char *fn) {
size_t size;
char afm_line[65535];
- int afm_size[1];
+ int afm_size[2];
FILE *afm_file;
char *str;
@@ -1492,7 +2414,8 @@ static int map_readafm(int m,char *fn) {
map[m].m = m;
xs = map[m].xs = afm_size[0];
ys = map[m].ys = afm_size[1];
- map[m].gat = calloc(s = map[m].xs * map[m].ys, 1);
+ // check this, unsigned where it might not need to be
+ map[m].gat = (unsigned char*)aCallocA(s = map[m].xs * map[m].ys, 1);
if(map[m].gat==NULL){
printf("out of memory : map_readmap gat\n");
@@ -1515,14 +2438,14 @@ static int map_readafm(int m,char *fn) {
map[m].bxs=(xs+BLOCK_SIZE-1)/BLOCK_SIZE;
map[m].bys=(ys+BLOCK_SIZE-1)/BLOCK_SIZE;
size = map[m].bxs * map[m].bys * sizeof(struct block_list*);
- map[m].block = calloc(size, 1);
+ map[m].block = (struct block_list**)aCalloc(size, 1);
if(map[m].block == NULL){
printf("out of memory : map_readmap block\n");
exit(1);
}
- map[m].block_mob = calloc(size, 1);
+ map[m].block_mob = (struct block_list**)aCalloc(size, 1);
if (map[m].block_mob == NULL) {
printf("out of memory : map_readmap block_mob\n");
exit(1);
@@ -1530,14 +2453,14 @@ static int map_readafm(int m,char *fn) {
size = map[m].bxs*map[m].bys*sizeof(int);
- map[m].block_count = calloc(size, 1);
+ map[m].block_count = (int*)aCallocA(size, 1);
if(map[m].block_count==NULL){
printf("out of memory : map_readmap block\n");
exit(1);
}
memset(map[m].block_count,0,size);
- map[m].block_mob_count=calloc(size, 1);
+ map[m].block_mob_count = (int*)aCallocA(size, 1);
if(map[m].block_mob_count==NULL){
printf("out of memory : map_readmap block_mob\n");
exit(1);
@@ -1552,58 +2475,100 @@ static int map_readafm(int m,char *fn) {
return 0;
}
+#endif
/*==========================================
* ƒ}ƒbƒv1–‡“ǂݞ‚Ý
- *------------------------------------------
- */
-static int map_readmap(int m,char *fn, char *alias) {
- unsigned char *gat="";
- int s;
- int x,y,xs,ys;
- struct gat_1cell {float high[4]; int type;} *p=NULL;
- int wh;
+ * ===================================================*/
+static int map_readmap(int m,char *fn, char *alias, int *map_cache, int maxmap) {
+ char *gat="";
size_t size;
- // read & convert fn
- gat=grfio_read(fn);
- if(gat==NULL)
- return -1;
+ int i = 0;
+ int e = 0;
+ char progress[21] = " ";
+
+ //printf("\rLoading Maps [%d/%d]: %-50s ",m,map_num,fn);
+ if (maxmap) { //avoid map-server crashing if there are 0 maps
+ char c = '-';
+ static int lasti = -1;
+ static int last_time = -1;
+ i=m*20/maxmap;
+ if ((i != lasti) || (last_time != time(0))) {
+ lasti = i;
+ printf("\r");
+ ShowStatus("Progress: ");
+ printf("[");
+ for (e=0;e<i;e++) progress[e] = '#';
+ printf(progress);
+ printf("] Working: [");
+ last_time = time(0);
+ switch(last_time % 4) {
+ case 0: c='\\'; break;
+ case 1: c='|'; break;
+ case 2: c='/'; break;
+ case 3: c='-'; break;
+ }
+ printf("%c]",c);
+ fflush(stdout);
+ }
+ }
-// printf("\rLoading Maps [%d/%d]: %-50s ",m,map_num,fn);
-// fflush(stdout);
+ if(map_cache_read(&map[m])) {
+ // ƒLƒƒƒbƒVƒ…‚©‚ç“ǂݞ‚ß‚½
+ (*map_cache)++;
+ } else {
+ int s;
+ int wh;
+ int x,y,xs,ys;
+ struct gat_1cell {float high[4]; int type;} *p=NULL;
+ // read & convert fn
+ // again, might not need to be unsigned char
+ gat = (char*)grfio_read(fn);
+ if(gat==NULL) {
+ return -1;
+ // ‚³‚·‚ª‚Ƀ}ƒbƒv‚ª“ǂ߂Ȃ¢‚̂͂܂¸‚¢‚Ì‚ÅI—¹‚·‚é
+ //printf("Can't load map %s\n",fn);
+ //exit(1);
+ }
- map[m].m=m;
- xs=map[m].xs=*(int*)(gat+6);
- ys=map[m].ys=*(int*)(gat+10);
- map[m].gat = (unsigned char *)aCalloc(s = map[m].xs * map[m].ys,sizeof(unsigned char));
- map[m].npc_num=0;
- map[m].users=0;
- memset(&map[m].flag,0,sizeof(map[m].flag));
- if(battle_config.pk_mode) map[m].flag.pvp = 1; // make all maps pvp for pk_mode [Valaris]
- wh=map_waterheight(map[m].name);
- for(y=0;y<ys;y++){
- p=(struct gat_1cell*)(gat+y*xs*20+14);
- for(x=0;x<xs;x++){
- if(wh!=NO_WATER && p->type==0){
- // …ê”»’è
- map[m].gat[x+y*xs]=(p->high[0]>wh || p->high[1]>wh || p->high[2]>wh || p->high[3]>wh) ? 3 : 0;
- } else {
- map[m].gat[x+y*xs]=p->type;
+ xs=map[m].xs=*(int*)(gat+6);
+ ys=map[m].ys=*(int*)(gat+10);
+ map[m].gat = (unsigned char *)aCallocA(s = map[m].xs * map[m].ys,sizeof(unsigned char));
+ wh=map_waterheight(map[m].name);
+ for(y=0;y<ys;y++){
+ p=(struct gat_1cell*)(gat+y*xs*20+14);
+ for(x=0;x<xs;x++){
+ if(wh!=NO_WATER && p->type==0){
+ // …ê”»’è
+ map[m].gat[x+y*xs]=(p->high[0]>wh || p->high[1]>wh || p->high[2]>wh || p->high[3]>wh) ? 3 : 0;
+ } else {
+ map[m].gat[x+y*xs]=p->type;
+ }
+ p++;
}
- p++;
}
+ map_cache_write(&map[m]);
+ aFree(gat);
}
- free(gat);
- map[m].bxs=(xs+BLOCK_SIZE-1)/BLOCK_SIZE;
- map[m].bys=(ys+BLOCK_SIZE-1)/BLOCK_SIZE;
+ map[m].m=m;
+ map[m].npc_num=0;
+ map[m].users=0;
+ memset(&map[m].flag,0,sizeof(map[m].flag));
+ if(battle_config.pk_mode)
+ map[m].flag.pvp = 1; // make all maps pvp for pk_mode [Valaris]
+ map[m].bxs=(map[m].xs+BLOCK_SIZE-1)/BLOCK_SIZE;
+ map[m].bys=(map[m].ys+BLOCK_SIZE-1)/BLOCK_SIZE;
size = map[m].bxs * map[m].bys * sizeof(struct block_list*);
map[m].block = (struct block_list **)aCalloc(1,size);
map[m].block_mob = (struct block_list **)aCalloc(1,size);
size = map[m].bxs*map[m].bys*sizeof(int);
- map[m].block_count = (int *)aCalloc(1,size);
- map[m].block_mob_count=(int *)aCalloc(1,size);
+ map[m].block_count = (int *)aCallocA(1,size);
+ map[m].block_mob_count=(int *)aCallocA(1,size);
+ if (alias)
+ strdb_insert(map_db,alias,&map[m]);
+ else
strdb_insert(map_db,map[m].name,&map[m]);
// printf("%s read done\n",fn);
@@ -1612,57 +2577,90 @@ static int map_readmap(int m,char *fn, char *alias) {
}
/*==========================================
- * ‘S‚Ä‚Ìmapƒf[ƒ^‚ð“ǂݞ‚Þ
+ * ‘S‚Ä‚Ìmapƒf?ƒ^‚ð?‚Ý?‚Þ
*------------------------------------------
*/
int map_readallmap(void) {
int i,maps_removed=0;
char fn[256];
+#ifdef USE_AFM
FILE *afm_file;
+#endif
+ int map_cache = 0;
+
+ // ƒ}ƒbƒvƒLƒƒƒbƒVƒ…‚ðŠJ‚­
+ if(map_read_flag >= READ_FROM_BITMAP) {
+ map_cache_open(map_cache_file);
+ }
+
+ sprintf(tmp_output, "Loading Maps%s...\n",
+ (map_read_flag == CREATE_BITMAP_COMPRESSED ? " (Generating Map Cache w/ Compression)" :
+ map_read_flag == CREATE_BITMAP ? " (Generating Map Cache)" :
+ map_read_flag >= READ_FROM_BITMAP ? " (w/ Map Cache)" :
+ map_read_flag == READ_FROM_AFM ? " (w/ AFM)" : ""));
+ ShowStatus(tmp_output);
// æ‚É‘S•”‚̃ƒbƒv‚Ì‘¶Ý‚ðŠm”F
for(i=0;i<map_num;i++){
- char afm_name[256] = "";
- strncpy(afm_name, map[i].name, strlen(map[i].name) - 4);
- strcat(afm_name, ".afm");
+#ifdef USE_AFM
+ char afm_name[256] = "";
+ char *p;
+ if(!strstr(map[i].name,".afm")) {
+ // check if it's necessary to replace the extension - speeds up loading abit
+ strncpy(afm_name, map[i].name, strlen(map[i].name) - 4);
+ strcat(afm_name, ".afm");
+ }
+ map[i].alias = NULL;
sprintf(fn,"%s\\%s",afm_dir,afm_name);
+ for(p=&fn[0];*p!=0;p++) if (*p=='\\') *p = '/'; // * At the time of Unix
+
afm_file = fopen(fn, "r");
if (afm_file != NULL) {
map_readafm(i,fn);
fclose(afm_file);
}
else if(strstr(map[i].name,".gat")!=NULL) {
- char *p = strstr(map[i].name, ">"); // [MouseJstr]
+#else
+ if(strstr(map[i].name,".gat")!=NULL) {
+#endif
+ char *p = strstr(map[i].name, "<"); // [MouseJstr]
if (p != NULL) {
- char alias[64];
- *p = '\0';
- strcpy(alias, map[i].name);
- strcpy(map[i].name, p + 1);
- sprintf(fn,"data\\%s",map[i].name);
- if(map_readmap(i,fn, alias) == -1) {
- map_delmap(map[i].name);
- maps_removed++;
- }
- } else {
- sprintf(fn,"data\\%s",map[i].name);
- if(map_readmap(i,fn, NULL) == -1) {
- map_delmap(map[i].name);
- maps_removed++;
- }
+ char buf[64];
+ *p++ = '\0';
+ sprintf(buf,"data\\%s", p);
+ map[i].alias = aStrdup(buf);
+ } else
+ map[i].alias = NULL;
+
+ sprintf(fn,"data\\%s",map[i].name);
+ if(map_readmap(i,fn, p, &map_cache, map_num) == -1) {
+ map_delmap(map[i].name);
+ maps_removed++;
+ i--;
}
}
}
- free(waterlist);
- printf("\rMaps Loaded: %d %60s\n",map_num,"");
- printf("\rMaps Removed: %d \n",maps_removed);
+ aFree(waterlist);
+ printf("\r");
+ snprintf(tmp_output,sizeof(tmp_output),"Successfully loaded '"CL_WHITE"%d"CL_RESET"' maps.%30s\n",map_num,"");
+ ShowInfo(tmp_output);
+
+ map_cache_close();
+ if(map_read_flag == CREATE_BITMAP || map_read_flag == CREATE_BITMAP_COMPRESSED) {
+ --map_read_flag;
+ }
+ if (maps_removed) {
+ snprintf(tmp_output,sizeof(tmp_output),"Maps Removed: '"CL_WHITE"%d"CL_RESET"'\n",maps_removed);
+ ShowNotice(tmp_output);
+ }
return 0;
}
/*==========================================
- * “ǂݞ‚Þmap‚ð’ljÁ‚·‚é
+ * ?‚Ý?‚Þmap‚ð’ljÁ‚·‚é
*------------------------------------------
*/
int map_addmap(char *mapname) {
@@ -1672,7 +2670,9 @@ int map_addmap(char *mapname) {
}
if (map_num >= MAX_MAP_PER_SERVER - 1) {
- printf("too many map\n");
+ snprintf(tmp_output,sizeof(tmp_output),"Could not add map '"
+ CL_WHITE"%s"CL_RESET"', the limit of maps has been reached.\n",mapname);
+ ShowError(tmp_output);
return 1;
}
memcpy(map[map_num].name, mapname, 24);
@@ -1681,7 +2681,7 @@ int map_addmap(char *mapname) {
}
/*==========================================
- * “ǂݞ‚Þmap‚ð휂·‚é
+ * ?‚Ý?‚Þmap‚ð휂·‚é
*------------------------------------------
*/
int map_delmap(char *mapname) {
@@ -1705,6 +2705,7 @@ int map_delmap(char *mapname) {
static int map_ip_set_ = 0;
static int char_ip_set_ = 0;
+//static int bind_ip_set_ = 0;
/*==========================================
* Console Command Parser [Wizputer]
@@ -1716,15 +2717,15 @@ int parse_console(char *buf) {
int m, n;
struct map_session_data *sd;
- sd = calloc(sizeof(*sd), 1);
+ sd = (struct map_session_data*)aCalloc(sizeof(*sd), 1);
sd->fd = 0;
strcpy( sd->status.name , "console");
- type = (char *)malloc(64);
- command = (char *)malloc(64);
- map = (char *)malloc(64);
- buf2 = (char *)malloc(72);
+ type = (char *)aMallocA(64);
+ command = (char *)aMallocA(64);
+ map = (char *)aMallocA(64);
+ buf2 = (char *)aMallocA(72);
memset(type,0,64);
memset(command,0,64);
@@ -1781,18 +2782,18 @@ int parse_console(char *buf) {
}
end:
- free(buf);
- free(type);
- free(command);
- free(map);
- free(buf2);
- free(sd);
+ aFree(buf);
+ aFree(type);
+ aFree(command);
+ aFree(map);
+ aFree(buf2);
+ aFree(sd);
return 0;
}
/*==========================================
- * Ý’èƒtƒ@ƒCƒ‹‚ð“ǂݞ‚Þ
+ * Ý’èƒtƒ@ƒCƒ‹‚ð?‚Ý?‚Þ
*------------------------------------------
*/
int map_config_read(char *cfgName) {
@@ -1817,7 +2818,7 @@ int map_config_read(char *cfgName) {
char_ip_set_ = 1;
h = gethostbyname (w2);
if(h != NULL) {
- snprintf(tmp_output,sizeof(tmp_output),"Character server IP address : %s -> %d.%d.%d.%d\n", w2, (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+ snprintf(tmp_output,sizeof(tmp_output),"Char Server IP Address : '"CL_WHITE"%s"CL_RESET"' -> '"CL_WHITE"%d.%d.%d.%d"CL_RESET"'.\n", w2, (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
ShowInfo(tmp_output);
sprintf(w2,"%d.%d.%d.%d", (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
}
@@ -1828,10 +2829,20 @@ int map_config_read(char *cfgName) {
map_ip_set_ = 1;
h = gethostbyname (w2);
if (h != NULL) {
- printf("Map server IP address : %s -> %d.%d.%d.%d\n", w2, (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+ snprintf(tmp_output,sizeof(tmp_output),"Map Server IP Address : '"CL_WHITE"%s"CL_RESET"' -> '"CL_WHITE"%d.%d.%d.%d"CL_RESET"'.\n", w2, (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+ ShowInfo(tmp_output);
sprintf(w2, "%d.%d.%d.%d", (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
}
clif_setip(w2);
+ } else if (strcmpi(w1, "bind_ip") == 0) {
+ //bind_ip_set_ = 1;
+ h = gethostbyname (w2);
+ if (h != NULL) {
+ snprintf(tmp_output,sizeof(tmp_output),"Map Server IP Address : '"CL_WHITE"%s"CL_RESET"' -> '"CL_WHITE"%d.%d.%d.%d"CL_RESET"'.\n", w2, (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+ ShowInfo(tmp_output);
+ sprintf(w2, "%d.%d.%d.%d", (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+ }
+ clif_setbindip(w2);
} else if (strcmpi(w1, "map_port") == 0) {
clif_setport(atoi(w2));
map_port = (atoi(w2));
@@ -1861,11 +2872,22 @@ int map_config_read(char *cfgName) {
strcpy(help_txt, w2);
} else if (strcmpi(w1, "mapreg_txt") == 0) {
strcpy(mapreg_txt, w2);
+ }else if(strcmpi(w1,"read_map_from_cache")==0){
+ if (atoi(w2) == 2)
+ map_read_flag = READ_FROM_BITMAP_COMPRESSED;
+ else if (atoi(w2) == 1)
+ map_read_flag = READ_FROM_BITMAP;
+ else
+ map_read_flag = READ_FROM_GAT;
+ }else if(strcmpi(w1,"map_cache_file")==0){
+ strncpy(map_cache_file,w2,255);
} else if (strcmpi(w1, "import") == 0) {
map_config_read(w2);
} else if (strcmpi(w1, "console") == 0) {
- if(strcmpi(w2,"on") == 0 || strcmpi(w2,"yes") == 0 )
+ if(strcmpi(w2,"on") == 0 || strcmpi(w2,"yes") == 0 ) {
console = 1;
+ ShowNotice("Console Commands is enabled.\n");
+ }
} else if(strcmpi(w1,"imalive_on")==0){ //Added by Mugendai for I'm Alive mod
imalive_on = atoi(w2); //Added by Mugendai for I'm Alive mod
} else if(strcmpi(w1,"imalive_time")==0){ //Added by Mugendai for I'm Alive mod
@@ -1883,82 +2905,7 @@ int map_config_read(char *cfgName) {
return 0;
}
-#ifndef TXT_ONLY
-/*=======================================
- * MySQL Init
- *---------------------------------------
- */
-
-int map_sql_init(void){
-
- mysql_init(&mmysql_handle);
-
- //DB connection start
- printf("Connect Map DB Server....\n");
- if(!mysql_real_connect(&mmysql_handle, map_server_ip, map_server_id, map_server_pw,
- map_server_db ,map_server_port, (char *)NULL, 0)) {
- //pointer check
- printf("%s\n",mysql_error(&mmysql_handle));
- exit(1);
- }
- else {
- printf ("connect success! (Map Server Connection)\n");
- }
-
- mysql_init(&lmysql_handle);
-
- //DB connection start
- printf("Connect Login DB Server....\n");
- if(!mysql_real_connect(&lmysql_handle, login_server_ip, login_server_id, login_server_pw,
- login_server_db ,login_server_port, (char *)NULL, 0)) {
- //pointer check
- printf("%s\n",mysql_error(&lmysql_handle));
- exit(1);
- }
- else {
- printf ("connect success! (Login Server Connection)\n");
- }
-
- if(battle_config.mail_system) { // mail system [Valaris]
- mysql_init(&mail_handle);
- if(!mysql_real_connect(&mail_handle, map_server_ip, map_server_id, map_server_pw,
- map_server_db ,map_server_port, (char *)NULL, 0)) {
- printf("%s\n",mysql_error(&mail_handle));
- exit(1);
- }
- }
-
- return 0;
-}
-
-int map_sql_close(void){
- mysql_close(&mmysql_handle);
- printf("Close Map DB Connection....\n");
-
- mysql_close(&lmysql_handle);
- printf("Close Login DB Connection....\n");
- return 0;
-}
-
-int log_sql_init(void){
-
- mysql_init(&mmysql_handle);
-
- //DB connection start
- printf("\033[1;29m[SQL]\033[0;0m: Connecting to Log Database \033[1;29m%s\033[0;0m At \033[1;29m%s\033[0;0m...\n",log_db,log_db_ip);
- if(!mysql_real_connect(&mmysql_handle, log_db_ip, log_db_id, log_db_pw,
- log_db ,log_db_port, (char *)NULL, 0)) {
- //pointer check
- printf("\033[1;29m[SQL Error]\033[0;0m: %s\n",mysql_error(&mmysql_handle));
- exit(1);
- } else {
- printf("\033[1;29m[SQL]\033[0;0m: Successfully \033[1;32mconnected\033[0;0m to Database \033[1;29m%s\033[0;0m.\n", log_db);
- }
-
- return 0;
-}
-
-int sql_config_read(char *cfgName)
+int inter_config_read(char *cfgName)
{
int i;
char line[1024],w1[1024],w2[1024];
@@ -1966,7 +2913,8 @@ int sql_config_read(char *cfgName)
fp=fopen(cfgName,"r");
if(fp==NULL){
- printf("file not found: %s\n",cfgName);
+ snprintf(tmp_output,sizeof(tmp_output),"File not found: '%s'.\n",cfgName);
+ ShowError(tmp_output);
return 1;
}
while(fgets(line,1020,fp)){
@@ -1975,7 +2923,11 @@ int sql_config_read(char *cfgName)
i=sscanf(line,"%[^:]: %[^\r\n]",w1,w2);
if(i!=2)
continue;
- if(strcmpi(w1,"item_db_db")==0){
+ //support the import command, just like any other config
+ if(strcmpi(w1,"import")==0){
+ inter_config_read(w2);
+ #ifndef TXT_ONLY
+ } else if(strcmpi(w1,"item_db_db")==0){
strcpy(item_db_db,w2);
} else if(strcmpi(w1,"mob_db_db")==0){
strcpy(mob_db_db,w2);
@@ -1996,45 +2948,32 @@ int sql_config_read(char *cfgName)
//Map Server SQL DB
} else if(strcmpi(w1,"map_server_ip")==0){
strcpy(map_server_ip, w2);
- printf ("set map_server_ip : %s\n",w2);
} else if(strcmpi(w1,"map_server_port")==0){
map_server_port=atoi(w2);
- printf ("set map_server_port : %s\n",w2);
} else if(strcmpi(w1,"map_server_id")==0){
strcpy(map_server_id, w2);
- printf ("set map_server_id : %s\n",w2);
} else if(strcmpi(w1,"map_server_pw")==0){
strcpy(map_server_pw, w2);
- printf ("set map_server_pw : %s\n",w2);
} else if(strcmpi(w1,"map_server_db")==0){
strcpy(map_server_db, w2);
- printf ("set map_server_db : %s\n",w2);
- //Map server option to use SQL db or not
} else if(strcmpi(w1,"use_sql_db")==0){
- if (strcmpi(w2,"yes")){db_use_sqldbs=0;} else if (strcmpi(w2,"no")){db_use_sqldbs=1;}
+ db_use_sqldbs = battle_config_switch(w2);
printf ("Using SQL dbs: %s\n",w2);
//Login Server SQL DB
} else if(strcmpi(w1,"login_server_ip")==0){
strcpy(login_server_ip, w2);
- printf ("set login_server_ip : %s\n",w2);
} else if(strcmpi(w1,"login_server_port")==0){
login_server_port = atoi(w2);
- printf ("set login_server_port : %s\n",w2);
} else if(strcmpi(w1,"login_server_id")==0){
strcpy(login_server_id, w2);
- printf ("set login_server_id : %s\n",w2);
} else if(strcmpi(w1,"login_server_pw")==0){
strcpy(login_server_pw, w2);
- printf ("set login_server_pw : %s\n",w2);
} else if(strcmpi(w1,"login_server_db")==0){
strcpy(login_server_db, w2);
- printf ("set login_server_db : %s\n",w2);
} else if(strcmpi(w1,"lowest_gm_level")==0){
lowest_gm_level = atoi(w2);
- printf ("set lowest_gm_level : %s\n",w2);
} else if(strcmpi(w1,"read_gm_interval")==0){
read_gm_interval = ( atoi(w2) * 60 * 1000 ); // Minutes multiplied by 60 secs per min by 1000 milliseconds per second
- printf ("set read_gm_interval : %s\n",w2);
} else if(strcmpi(w1,"log_db")==0) {
strcpy(log_db, w2);
} else if(strcmpi(w1,"log_db_ip")==0) {
@@ -2047,9 +2986,7 @@ int sql_config_read(char *cfgName)
strcpy(log_db_pw, w2);
} else if(strcmpi(w1,"log_db_port")==0) {
log_db_port = atoi(w2);
- //support the import command, just like any other config
- } else if(strcmpi(w1,"import")==0){
- sql_config_read(w2);
+ #endif
}
}
fclose(fp);
@@ -2057,63 +2994,100 @@ int sql_config_read(char *cfgName)
return 0;
}
-// sql online status checking [Valaris]
-void char_offline(struct map_session_data *sd)
-{
- if(sd && sd->status.char_id) {
- sprintf(tmp_sql,"UPDATE `%s` SET `online`='0' WHERE `char_id`='%d'", char_db, sd->status.char_id);
- if(mysql_query(&mmysql_handle, tmp_sql) ) {
- printf("DB server Error (update online `%s`)- %s\n", char_db, mysql_error(&mmysql_handle) );
- }
+#ifndef TXT_ONLY
+/*=======================================
+ * MySQL Init
+ *---------------------------------------
+ */
+
+int map_sql_init(void){
+
+ mysql_init(&mmysql_handle);
+
+ //DB connection start
+ printf("Connect Map DB Server....\n");
+ if(!mysql_real_connect(&mmysql_handle, map_server_ip, map_server_id, map_server_pw,
+ map_server_db ,map_server_port, (char *)NULL, 0)) {
+ //pointer check
+ printf("%s\n",mysql_error(&mmysql_handle));
+ exit(1);
+ }
+ else {
+ printf ("connect success! (Map Server Connection)\n");
}
-}
-void do_reset_online(void)
-{
- sprintf(tmp_sql,"UPDATE `%s` SET `online`='0' WHERE `online`='1'", char_db);
- if(mysql_query(&mmysql_handle, tmp_sql) ) {
- printf("DB server Error (reset_online `%s`)- %s\n", char_db, mysql_error(&mmysql_handle) );
+ mysql_init(&lmysql_handle);
+
+ //DB connection start
+ printf("Connect Login DB Server....\n");
+ if(!mysql_real_connect(&lmysql_handle, login_server_ip, login_server_id, login_server_pw,
+ login_server_db ,login_server_port, (char *)NULL, 0)) {
+ //pointer check
+ printf("%s\n",mysql_error(&lmysql_handle));
+ exit(1);
+ }
+ else {
+ printf ("connect success! (Login Server Connection)\n");
+ }
+
+ if(battle_config.mail_system) { // mail system [Valaris]
+ mysql_init(&mail_handle);
+ if(!mysql_real_connect(&mail_handle, map_server_ip, map_server_id, map_server_pw,
+ map_server_db ,map_server_port, (char *)NULL, 0)) {
+ printf("%s\n",mysql_error(&mail_handle));
+ exit(1);
+ }
}
+
+ return 0;
}
-int online_timer(int tid,unsigned int tick,int id,int data)
-{
- if(check_online_timer != tid)
- return 0;
+int map_sql_close(void){
+ mysql_close(&mmysql_handle);
+ printf("Close Map DB Connection....\n");
- char_online_check();
+ mysql_close(&lmysql_handle);
+ printf("Close Login DB Connection....\n");
+ return 0;
+}
+
+int log_sql_init(void){
+
+ mysql_init(&mmysql_handle);
- check_online_timer=add_timer(gettick()+CHECK_INTERVAL,online_timer,0,0);
+ //DB connection start
+ printf(""CL_WHITE"[SQL]"CL_RESET": Connecting to Log Database "CL_WHITE"%s"CL_RESET" At "CL_WHITE"%s"CL_RESET"...\n",log_db,log_db_ip);
+ if(!mysql_real_connect(&mmysql_handle, log_db_ip, log_db_id, log_db_pw,
+ log_db ,log_db_port, (char *)NULL, 0)) {
+ //pointer check
+ printf(""CL_WHITE"[SQL Error]"CL_RESET": %s\n",mysql_error(&mmysql_handle));
+ exit(1);
+ } else {
+ printf(""CL_WHITE"[SQL]"CL_RESET": Successfully '"CL_GREEN"connected"CL_RESET"' to Database '"CL_WHITE"%s"CL_RESET"'.\n", log_db);
+ }
return 0;
}
+int online_timer (int tid,unsigned int tick,int id,int data)
+{
+ char_online_check();
+ return 0;
+}
void char_online_check(void)
{
int i;
- struct map_session_data *sd=NULL;
-
- do_reset_online();
+ struct map_session_data *sd;
- for(i=0;i<fd_max;i++){
- if (session[i] && (sd = session[i]->session_data) && sd && sd->state.auth &&
- !(battle_config.hide_GM_session && pc_isGM(sd)))
- if(sd->status.char_id) {
- sprintf(tmp_sql,"UPDATE `%s` SET `online`='1' WHERE `char_id`='%d'", char_db, sd->status.char_id);
- if(mysql_query(&mmysql_handle, tmp_sql) ) {
- printf("DB server Error (update online `%s`)- %s\n", char_db, mysql_error(&mmysql_handle) );
- }
- }
- }
+ chrif_char_reset_offline();
-
- if(check_online_timer && check_online_timer != -1) {
- delete_timer(check_online_timer,online_timer);
- add_timer(gettick()+CHECK_INTERVAL,online_timer,0,0);
+ for (i = 0; i < fd_max; i++) {
+ if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) && sd->state.auth &&
+ !(battle_config.hide_GM_session && pc_isGM(sd)))
+ if(sd->status.char_id)
+ chrif_char_online(sd);
}
-
}
-
#endif /* not TXT_ONLY */
//-----------------------------------------------------
@@ -2135,23 +3109,32 @@ int flush_timer(int tid, unsigned int tick, int id, int data){
return 0;
}
-int id_db_final(void *k,void *d,va_list ap){ return 0; }
-int map_db_final(void *k,void *d,va_list ap){ return 0; }
-int nick_db_final(void *k,void *d,va_list ap){ return 0; }
-int charid_db_final(void *k,void *d,va_list ap){ return 0; }
-
-static int cleanup_sub(struct block_list *bl, va_list ap) {
+int id_db_final(void *k,void *d,va_list ap) { return 0; }
+int map_db_final(void *k,void *d,va_list ap) { return 0; }
+int nick_db_final(void *k,void *d,va_list ap)
+{
+ char *p = (char *) d;
+ if (p) aFree(p);
+ return 0;
+}
+int charid_db_final(void *k,void *d,va_list ap)
+{
+ struct charid2nick *p = (struct charid2nick *) d;
+ if (p) aFree(p);
+ return 0;
+}
+int cleanup_sub(struct block_list *bl, va_list ap) {
nullpo_retr(0, bl);
switch(bl->type) {
case BL_PC:
- map_delblock(bl); // There is something better...
+ map_quit((struct map_session_data *) bl);
break;
case BL_NPC:
- npc_delete((struct npc_data *)bl);
+ npc_unload((struct npc_data *)bl);
break;
case BL_MOB:
- mob_delete((struct mob_data *)bl);
+ mob_unload((struct mob_data *)bl);
break;
case BL_PET:
pet_remove_map((struct map_session_data *)bl);
@@ -2168,47 +3151,100 @@ static int cleanup_sub(struct block_list *bl, va_list ap) {
}
/*==========================================
- * mapŽII—¹Žžˆ—
+ * mapŽII—¹Žž?—
*------------------------------------------
*/
void do_final(void) {
- int map_id, i;
+ int i;
+ ShowStatus("Terminating...\n");
- for (map_id = 0; map_id < map_num;map_id++) {
- if(map[map_id].m)
- map_foreachinarea(cleanup_sub, map_id, 0, 0, map[map_id].xs, map[map_id].ys, 0, 0);
- }
+ for (i = 0; i < map_num; i++)
+ if(map[i].m)
+ map_foreachinarea(cleanup_sub, i, 0, 0, map[i].xs, map[i].ys, 0, 0);
- for (i = 0; i < fd_max; i++)
- delete_session(i);
+#ifndef TXT_ONLY
+ chrif_char_reset_offline();
+#endif
- map_removenpc();
- timer_final();
+ chrif_flush_fifo();
+
+//#if 0 // why is this here? >_>
+ do_final_chrif(); // ‚±‚Ì“à•”‚ŃLƒƒƒ‰‚ð‘S‚ÄØ’f‚·‚é
+ do_final_npc();
+// map_removenpc();
+ do_final_script();
+ do_final_itemdb();
+ do_final_storage();
+ do_final_guild();
+ do_final_party();
+ do_final_pc();
+ do_final_pet();
+ do_final_msg();
+
+ for (i=0; i<map_num; i++) {
+ if(map[i].gat) aFree(map[i].gat);
+ if(map[i].block) aFree(map[i].block);
+ if(map[i].block_mob) aFree(map[i].block_mob);
+ if(map[i].block_count) aFree(map[i].block_count);
+ if(map[i].block_mob_count) aFree(map[i].block_mob_count);
+ }
+// do_final_timer(); (we used timer_final() instead)
+ timer_final();
numdb_final(id_db, id_db_final);
- strdb_final(map_db, map_db_final);
+ strdb_final(map_db, map_db_final);
strdb_final(nick_db, nick_db_final);
numdb_final(charid_db, charid_db_final);
+ exit_dbn();
+
+//#endif
- for(i=0;i<=map_num;i++){
- if(map[i].gat) free(map[i].gat);
- if(map[i].block) free(map[i].block);
- if(map[i].block_mob) free(map[i].block_mob);
- if(map[i].block_count) free(map[i].block_count);
- if(map[i].block_mob_count) free(map[i].block_mob_count);
- }
- do_final_script();
- do_final_itemdb();
- do_final_storage();
- do_final_guild();
#ifndef TXT_ONLY
- do_reset_online();
map_sql_close();
#endif /* not TXT_ONLY */
+ ShowStatus("Successfully terminated.\n");
}
-void map_helpscreen() {
- exit(1);
+/*======================================================
+ * Map-Server Version Screen [MC Cameri]
+ *------------------------------------------------------
+ */
+void map_helpscreen(int flag) { // by MC Cameri
+ puts("Usage: map-server [options]");
+ puts("Options:");
+ puts(CL_WHITE" Commands\t\t\tDescription"CL_RESET);
+ puts("-----------------------------------------------------------------------------");
+ puts(" --help, --h, --?, /? Displays this help screen");
+ puts(" --map-config <file> Load map-server configuration from <file>");
+ puts(" --battle-config <file> Load battle configuration from <file>");
+ puts(" --atcommand-config <file> Load atcommand configuration from <file>");
+ puts(" --charcommand-config <file> Load charcommand configuration from <file>");
+ puts(" --script-config <file> Load script configuration from <file>");
+ puts(" --msg-config <file> Load message configuration from <file>");
+ puts(" --grf-path-file <file> Load grf path file configuration from <file>");
+ puts(" --sql-config <file> Load inter-server configuration from <file>");
+ puts(" (SQL Only)");
+ puts(" --log-config <file> Load logging configuration from <file>");
+ puts(" (SQL Only)");
+ puts(" --version, --v, -v, /v Displays the server's version");
+ puts("\n");
+ if (flag) exit(1);
+}
+
+/*======================================================
+ * Map-Server Version Screen [MC Cameri]
+ *------------------------------------------------------
+ */
+void map_versionscreen(int flag) {
+ printf("CL_WHITE" "eAthena version %d.%02d.%02d, Athena Mod version %d" CL_RESET"\n",
+ ATHENA_MAJOR_VERSION, ATHENA_MINOR_VERSION, ATHENA_REVISION,
+ ATHENA_MOD_VERSION);
+ puts(CL_GREEN "Website/Forum:" CL_RESET "\thttp://eathena.deltaanime.net/");
+ puts(CL_GREEN "Download URL:" CL_RESET "\thttp://eathena.systeminplace.net/");
+ puts(CL_GREEN "IRC Channel:" CL_RESET "\tirc://irc.deltaanime.net/#athena");
+ puts("\nOpen " CL_WHITE "readme.html" CL_RESET " for more information.");
+ if (ATHENA_RELEASE_FLAG) ShowNotice("This version is not for release.\n");
+ if (flag) exit(1);
}
/*======================================================
@@ -2220,42 +3256,52 @@ int do_init(int argc, char *argv[]) {
FILE *data_conf;
char line[1024], w1[1024], w2[1024];
-#ifndef TXT_ONLY
- unsigned char *SQL_CONF_NAME="conf/inter_athena.conf";
- unsigned char *LOG_CONF_NAME="conf/log_athena.conf";
+ SERVER_TYPE = SERVER_MAP;
+#ifdef GCOLLECT
+ GC_enable_incremental();
#endif
- unsigned char *MAP_CONF_NAME = "conf/map_athena.conf";
- unsigned char *BATTLE_CONF_FILENAME = "conf/battle_athena.conf";
- unsigned char *ATCOMMAND_CONF_FILENAME = "conf/atcommand_athena.conf";
- unsigned char *CHARCOMMAND_CONF_FILENAME = "conf/charcommand_athena.conf";
- unsigned char *SCRIPT_CONF_NAME = "conf/script_athena.conf";
- unsigned char *MSG_CONF_NAME = "conf/msg_athena.conf";
- unsigned char *GRF_PATH_FILENAME = "conf/grf-files.txt";
+
+ INTER_CONF_NAME="conf/inter_athena.conf";
+ LOG_CONF_NAME="conf/log_athena.conf";
+ MAP_CONF_NAME = "conf/map_athena.conf";
+ BATTLE_CONF_FILENAME = "conf/battle_athena.conf";
+ ATCOMMAND_CONF_FILENAME = "conf/atcommand_athena.conf";
+ CHARCOMMAND_CONF_FILENAME = "conf/charcommand_athena.conf";
+ SCRIPT_CONF_NAME = "conf/script_athena.conf";
+ MSG_CONF_NAME = "conf/msg_athena.conf";
+ GRF_PATH_FILENAME = "conf/grf-files.txt";
+
+ chrif_connected = 0;
srand(gettick());
for (i = 1; i < argc ; i++) {
-
if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "--h") == 0 || strcmp(argv[i], "--?") == 0 || strcmp(argv[i], "/?") == 0)
- map_helpscreen();
- else if (strcmp(argv[i], "--map_config") == 0)
+ map_helpscreen(1);
+ if (strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "--v") == 0 || strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "/v") == 0)
+ map_versionscreen(1);
+ else if (strcmp(argv[i], "--map_config") == 0 || strcmp(argv[i], "--map-config") == 0)
MAP_CONF_NAME=argv[i+1];
- else if (strcmp(argv[i],"--battle_config") == 0)
+ else if (strcmp(argv[i],"--battle_config") == 0 || strcmp(argv[i],"--battle-config") == 0)
BATTLE_CONF_FILENAME = argv[i+1];
- else if (strcmp(argv[i],"--atcommand_config") == 0)
+ else if (strcmp(argv[i],"--atcommand_config") == 0 || strcmp(argv[i],"--atcommand-config") == 0)
ATCOMMAND_CONF_FILENAME = argv[i+1];
- else if (strcmp(argv[i],"--charcommand_config") == 0)
+ else if (strcmp(argv[i],"--charcommand_config") == 0 || strcmp(argv[i],"--charcommand-config") == 0)
CHARCOMMAND_CONF_FILENAME = argv[i+1];
- else if (strcmp(argv[i],"--script_config") == 0)
+ else if (strcmp(argv[i],"--script_config") == 0 || strcmp(argv[i],"--script-config") == 0)
SCRIPT_CONF_NAME = argv[i+1];
- else if (strcmp(argv[i],"--msg_config") == 0)
+ else if (strcmp(argv[i],"--msg_config") == 0 || strcmp(argv[i],"--msg-config") == 0)
MSG_CONF_NAME = argv[i+1];
- else if (strcmp(argv[i],"--grf_path_file") == 0)
+ else if (strcmp(argv[i],"--grf_path_file") == 0 || strcmp(argv[i],"--grf-path-file") == 0)
GRF_PATH_FILENAME = argv[i+1];
#ifndef TXT_ONLY
- else if (strcmp(argv[i],"--sql_config") == 0)
- SQL_CONF_NAME = argv[i+1];
+ else if (strcmp(argv[i],"--inter_config") == 0 || strcmp(argv[i],"--inter-config") == 0)
+ INTER_CONF_NAME = argv[i+1];
#endif /* not TXT_ONLY */
+ else if (strcmp(argv[i],"--log_config") == 0 || strcmp(argv[i],"--log-config") == 0)
+ LOG_CONF_NAME = argv[i+1];
+ else if (strcmp(argv[i],"--run_once") == 0) // close the map-server as soon as its done.. for testing [Celest]
+ runflag = 0;
}
map_config_read(MAP_CONF_NAME);
@@ -2285,16 +3331,14 @@ int do_init(int argc, char *argv[]) {
if (ptr[0] == 192 && ptr[1] == 168)
printf("\nFirewall detected.. \n edit lan_support.conf and map_athena.conf\n\n");
}
-
+ if (SHOW_DEBUG_MSG) ShowNotice("Server running in '"CL_WHITE"Debug Mode"CL_RESET"'.\n");
battle_config_read(BATTLE_CONF_FILENAME);
msg_config_read(MSG_CONF_NAME);
atcommand_config_read(ATCOMMAND_CONF_FILENAME);
charcommand_config_read(CHARCOMMAND_CONF_FILENAME);
script_config_read(SCRIPT_CONF_NAME);
-#ifndef TXT_ONLY
- sql_config_read(SQL_CONF_NAME);
+ inter_config_read(INTER_CONF_NAME);
log_config_read(LOG_CONF_NAME);
-#endif /* not TXT_ONLY */
atexit(do_final);
@@ -2323,45 +3367,48 @@ int do_init(int argc, char *argv[]) {
map_readallmap();
+ add_timer_func_list(map_freeblock_timer,"map_freeblock_timer");
add_timer_func_list(map_clearflooritem_timer, "map_clearflooritem_timer");
+ add_timer_interval(gettick()+1000,map_freeblock_timer,0,0,60*1000);
//Added by Mugendai for GUI support
if (flush_on)
- {
add_timer_interval(gettick()+10, flush_timer,0,0,flush_time);
- }
+ //Added for Mugendais I'm Alive mod
+ if (imalive_on)
+ add_timer_interval(gettick()+10, imalive_timer,0,0,imalive_time*1000);
#ifndef TXT_ONLY // online status timer, checks every hour [Valaris]
add_timer_func_list(online_timer, "online_timer");
- check_online_timer=add_timer(gettick()+CHECK_INTERVAL,online_timer,0,0);
+ add_timer_interval(gettick()+10, online_timer, 0, 0, CHECK_INTERVAL);
#endif /* not TXT_ONLY */
do_init_chrif();
do_init_clif();
do_init_itemdb();
- do_init_mob(); // npc‚̉Šú‰»Žž“à‚Åmob_spawn‚µ‚ÄAmob_db‚ðŽQÆ‚·‚é‚Ì‚Åinit_npc‚æ‚èæ
+ do_init_mob(); // npc‚̉Šú‰»Žž?‚Åmob_spawn‚µ‚ÄAmob_db‚ð?Æ‚·‚é‚Ì‚Åinit_npc‚æ‚èæ
do_init_script();
- do_init_npc();
do_init_pc();
+ do_init_status();
do_init_party();
do_init_guild();
do_init_storage();
do_init_skill();
do_init_pet();
+ do_init_npc();
#ifndef TXT_ONLY /* mail system [Valaris] */
if(battle_config.mail_system)
do_init_mail();
- if (log_config.branch || log_config.drop || log_config.mvpdrop ||
- log_config.present || log_config.produce || log_config.refine ||
- log_config.trade)
+ if (log_config.sql_logs && (log_config.branch || log_config.drop || log_config.mvpdrop ||
+ log_config.present || log_config.produce || log_config.refine || log_config.trade))
{
log_sql_init();
}
#endif /* not TXT_ONLY */
- npc_event_do_oninit(); // npc‚ÌOnInitƒCƒxƒ“ƒgŽÀs
+ npc_event_do_oninit(); // npc‚ÌOnInitƒCƒxƒ“ƒg?s
if ( console ) {
set_defaultconsoleparse(parse_console);
@@ -2369,15 +3416,22 @@ int do_init(int argc, char *argv[]) {
}
if (battle_config.pk_mode == 1)
- printf("The server is running in \033[1;31mPK Mode\033[0m.\n");
-
- //Added for Mugendais I'm Alive mod
- if (imalive_on)
- add_timer_interval(gettick()+10, imalive_timer,0,0,imalive_time*1000);
-
- printf("The map-server is \033[1;32mready\033[0m (Server is listening on the port %d).\n\n", map_port);
- ticks = gettick();
+ ShowNotice("Server is running on '"CL_WHITE"PK Mode"CL_RESET"'.\n");
+ sprintf(tmp_output,"Server is '"CL_GREEN"ready"CL_RESET"' and listening on port '"CL_WHITE"%d"CL_RESET"'.\n\n", map_port);
+ ShowStatus(tmp_output);
return 0;
}
+
+int compare_item(struct item *a, struct item *b) {
+ return (
+ (a->nameid == b->nameid) &&
+ (a->identify == b->identify) &&
+ (a->refine == b->refine) &&
+ (a->attribute == b->attribute) &&
+ (a->card[0] == b->card[0]) &&
+ (a->card[1] == b->card[1]) &&
+ (a->card[2] == b->card[2]) &&
+ (a->card[3] == b->card[3]));
+}
diff --git a/src/map/map.h b/src/map/map.h
index bf443bf46..01d9fef0e 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -10,7 +10,7 @@
#define PC_CLASS_BASE2 (PC_CLASS_BASE + 4001)
#define PC_CLASS_BASE3 (PC_CLASS_BASE2 + 22)
#define MAX_NPC_PER_MAP 512
-#define BLOCK_SIZE 8
+#define BLOCK_SIZE 8 // Never zero
#define AREA_SIZE battle_config.area_size
#define LOCAL_REG_NUM 16
#define LIFETIME_FLOORITEM 60
@@ -20,7 +20,7 @@
#define MAX_STATUSCHANGE 210
#define MAX_SKILLUNITGROUP 32
#define MAX_MOBSKILLUNITGROUP 8
-#define MAX_SKILLUNITGROUPTICKSET 128
+#define MAX_SKILLUNITGROUPTICKSET 32
#define MAX_SKILLTIMERSKILL 32
#define MAX_MOBSKILLTIMERSKILL 10
#define MAX_MOBSKILL 32
@@ -32,6 +32,7 @@
#define MAX_WALKPATH 32
#define MAX_DROP_PER_MAP 48
#define MAX_IGNORE_LIST 80
+#define MAX_VENDING 12
#define DEFAULT_AUTOSAVE_INTERVAL 60*1000
@@ -52,6 +53,12 @@ struct walkpath_data {
unsigned char path_len,path_pos,path_half;
unsigned char path[MAX_WALKPATH];
};
+struct shootpath_data {
+ int rx,ry,len;
+ int x[MAX_WALKPATH];
+ int y[MAX_WALKPATH];
+};
+
struct script_reg {
int index;
int data;
@@ -84,13 +91,13 @@ struct skill_unit_group {
int src_id;
int party_id;
int guild_id;
- int map,range;
+ int map;
int target_flag;
unsigned int tick;
int limit,interval;
int skill_id,skill_lv;
- int val1,val2;
+ int val1,val2,val3;
char *valstr;
int unit_id;
int group_id;
@@ -99,7 +106,7 @@ struct skill_unit_group {
};
struct skill_unit_group_tickset {
unsigned int tick;
- int group_id;
+ int id;
};
struct skill_timerskill {
int timer;
@@ -137,6 +144,12 @@ struct map_session_data {
unsigned make_arrow_flag : 1;
unsigned potionpitcher_flag : 1;
unsigned storage_flag : 1;
+ unsigned snovice_flag : 4;
+ int gmaster_flag;
+ // originally by Qamera, adapted by celest
+ unsigned event_death : 1;
+ unsigned event_kill : 1;
+ unsigned event_disconnect : 1;
} state;
struct {
unsigned killer : 1;
@@ -149,15 +162,14 @@ struct map_session_data {
unsigned no_weapon_damage : 1;
unsigned no_gemstone : 1;
unsigned infinite_endure : 1;
- unsigned unbreakable_weapon : 1;
- unsigned unbreakable_armor : 1;
- unsigned infinite_autospell : 1;
} special_state;
int char_id, login_id1, login_id2, sex;
int packet_ver; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
struct mmo_charstatus status;
struct item_data *inventory_data[MAX_INVENTORY];
short equip_index[11];
+ unsigned short unbreakable_equip;
+ unsigned short unbreakable; // chance to prevent equipment breaking [celest]
int weight,max_weight;
int cart_weight,cart_max_weight,cart_num,cart_max_num;
char mapname[24];
@@ -169,6 +181,7 @@ struct map_session_data {
unsigned int client_tick,server_tick;
struct walkpath_data walkpath;
int walktimer;
+ int next_walktime;
int npc_id,areanpc_id,npc_shopid;
int npc_pos;
int npc_menu;
@@ -178,6 +191,7 @@ struct map_session_data {
char *npc_stackbuf;
char npc_str[256];
unsigned int chatID;
+ unsigned long idletime;
struct{
char name[24];
@@ -192,6 +206,8 @@ struct map_session_data {
int followtimer; // [MouseJstr]
int followtarget;
+ time_t emotionlasttime; // to limit flood with emotion packets
+
short attackrange,attackrange_;
int skilltimer;
int skilltarget;
@@ -203,17 +219,21 @@ struct map_session_data {
struct skill_unit_group skillunit[MAX_SKILLUNITGROUP];
struct skill_unit_group_tickset skillunittick[MAX_SKILLUNITGROUPTICKSET];
struct skill_timerskill skilltimerskill[MAX_SKILLTIMERSKILL];
- int cloneskill_id,cloneskill_lv;
+ char blockskill[MAX_SKILL]; // [celest]
+ //unsigned int skillstatictimer[MAX_SKILL];
+ unsigned short timerskill_count; // [celest]
+ int cloneskill_id;
int potion_hp,potion_sp,potion_per_hp,potion_per_sp;
int invincible_timer;
unsigned int canact_tick;
unsigned int canmove_tick;
unsigned int canlog_tick;
+ unsigned int canregen_tick;
int hp_sub,sp_sub;
int inchealhptick,inchealsptick,inchealspirithptick,inchealspiritsptick;
// -- moonsoul (new tick for berserk self-damage)
- int berserkdamagetick;
+// int berserkdamagetick;
int fame;
short view_class;
@@ -224,12 +244,13 @@ struct map_session_data {
int watk,watk2,atkmods[3];
int def,def2,mdef,mdef2,critical,matk1,matk2;
int atk_ele,def_ele,star,overrefine;
- int castrate,hprate,sprate,dsprate;
+ int castrate,delayrate,hprate,sprate,dsprate;
int addele[10],addrace[12],addsize[3],subele[10],subrace[12];
int addeff[10],addeff2[10],reseff[10];
int watk_,watk_2,atkmods_[3],addele_[10],addrace_[12],addsize_[3]; //“ñ“—¬‚Ì‚½‚߂ɒljÁ
int atk_ele_,star_,overrefine_; //“ñ“—¬‚Ì‚½‚߂ɒljÁ
int base_atk,atk_rate;
+ int weapon_atk[16],weapon_atk_rate[16];
int arrow_atk,arrow_ele,arrow_cri,arrow_hit,arrow_range;
int arrow_addele[10],arrow_addrace[12],arrow_addsize[3],arrow_addeff[10],arrow_addeff2[10];
int nhealhp,nhealsp,nshealhp,nshealsp,nsshealhp,nsshealsp;
@@ -258,18 +279,42 @@ struct map_session_data {
short hp_drain_value,sp_drain_value,hp_drain_value_,sp_drain_value_;
int short_weapon_damage_return,long_weapon_damage_return;
int weapon_coma_ele[10],weapon_coma_race[12];
- short break_weapon_rate,break_armor_rate;
+ int break_weapon_rate,break_armor_rate;
short add_steal_rate;
+ //--- 02/15's new card effects [celest]
+ int crit_atk_rate;
+ int critaddrace[12];
+ short no_regen;
+ int addeff3[10];
+ short addeff3_type[10];
+ short autospell2_id,autospell2_lv,autospell2_rate,autospell2_type;
+ int skillatk[2];
+ unsigned short unstripable_equip;
+ short add_damage_classid2[10],add_damage_class_count2;
+ int add_damage_classrate2[10];
+ short sp_gain_value, hp_gain_value;
+ short sp_drain_type;
+ short ignore_def_mob, ignore_def_mob_;
+ int hp_loss_tick, hp_loss_rate;
+ short hp_loss_value, hp_loss_type;
+ int addrace2[12],addrace2_[12];
+ int subsize[3];
+ short unequip_losehp[11];
+ short unequip_losesp[11];
+ int itemid;
+ int itemhealrate[7];
+ //--- 03/15's new card effects
+ int expaddrace[12];
+ int subrace2[12];
+ short sp_gain_race[12];
short spiritball, spiritball_old;
int spirit_timer[MAX_SKILL_LEVEL];
int magic_damage_return; // AppleGirl Was Here
int random_attack_increase_add,random_attack_increase_per; // [Valaris]
int perfect_hiding; // [Valaris]
- int unbreakable;
int classchange; // [Valaris]
-
int die_counter;
short doridori_counter;
@@ -299,7 +344,7 @@ struct map_session_data {
int vender_id;
int vend_num;
char message[80];
- struct vending vending[12];
+ struct vending vending[MAX_VENDING];
int catch_target_class;
struct s_pet pet;
@@ -311,11 +356,15 @@ struct map_session_data {
char eventqueue[MAX_EVENTQUEUE][50];
int eventtimer[MAX_EVENTTIMER];
+ unsigned short eventcount; // [celest]
int last_skillid,last_skilllv; // Added by RoVeRT
- short sg_count;
unsigned char change_level; // [celest]
+ int autoloot; //by Upa-Kun
+ unsigned nodelay :1;
+ unsigned noexp :1;
+ unsigned detach :1;
#ifndef TXT_ONLY
int mail_counter; // mail counter for mail system [Valaris]
@@ -336,7 +385,7 @@ struct npc_item_list {
struct npc_data {
struct block_list bl;
short n;
- short class,dir;
+ short class_,dir;
short speed;
char name[24];
char exname[24];
@@ -360,7 +409,7 @@ struct npc_data {
char *script;
short xs,ys;
int guild_id;
- int timer,timerid,timeramount,nexttimer;
+ int timer,timerid,timeramount,nexttimer,rid;
unsigned int timertick;
struct npc_timerevent_list *timer_event;
int label_list_num;
@@ -379,11 +428,13 @@ struct npc_data {
char eventqueue[MAX_EVENTQUEUE][50];
int eventtimer[MAX_EVENTTIMER];
short arenaflag;
+
+ void *chatdb;
};
struct mob_data {
struct block_list bl;
short n;
- short base_class,class,dir,mode,level;
+ short base_class,class_,dir,mode,level;
short m,x0,y0,xs,ys;
char name[24];
int spawndelay1,spawndelay2;
@@ -398,9 +449,12 @@ struct mob_data {
unsigned change_walk_target : 1;
unsigned walk_easy : 1;
unsigned special_mob_ai : 3;
+ unsigned soul_change_flag : 1; // Celest
+ int provoke_flag; // Celest
} state;
int timer;
short to_x,to_y;
+ short target_dir;
short speed;
int hp;
int target_id,attacked_id;
@@ -422,7 +476,6 @@ struct mob_data {
short sc_count;
short opt1,opt2,opt3,option;
short min_chase;
- short sg_count;
int guild_id;
int deletetimer;
@@ -438,18 +491,22 @@ struct mob_data {
struct skill_unit_group skillunit[MAX_MOBSKILLUNITGROUP];
struct skill_unit_group_tickset skillunittick[MAX_SKILLUNITGROUPTICKSET];
char npc_event[50];
- short size;
+ unsigned char size;
+ short recall_flag;
+ int recallmob_count;
+ short recallcount;
};
struct pet_data {
struct block_list bl;
short n;
- short class,dir;
+ short class_,dir;
short speed;
char name[24];
struct {
unsigned state : 8 ;
unsigned skillstate : 8 ;
unsigned change_walk_target : 1 ;
+ short skillbonus;
} state;
int timer;
short to_x,to_y;
@@ -460,7 +517,8 @@ struct pet_data {
int move_fail_count;
unsigned int attackabletime,next_walktime,last_thinktime;
int skilltype,skillval,skilltimer,skillduration; // [Valaris]
- int skillbonustype,skillbonusval,skillbonustimer,skillbonusduration; // [Valaris]
+ //int skillbonustype,skillbonusval,skillbonustimer,skillbonusduration; // [Valaris]
+ int skillbonustype,skillbonusval,skillbonustimer;
struct item *lootitem;
short loot; // [Valaris]
short lootmax; // [Valaris]
@@ -479,10 +537,18 @@ enum { NONE_ATTACKABLE,ATTACKABLE };
enum { ATK_LUCKY=1,ATK_FLEE,ATK_DEF}; // ˆÍ‚Ü‚êƒyƒiƒ‹ƒeƒBŒvŽZ—p
+// ‘•”õƒR[ƒh
+enum {
+ EQP_WEAPON = 0x0002, // ‰EŽè
+ EQP_ARMOR = 0x0010, // ‘Ì
+ EQP_SHIELD = 0x0020, // ¶Žè
+ EQP_HELM = 0x0100, // “ªã’i
+};
+
struct map_data {
char name[24];
- char alias[24]; // [MouseJstr]
unsigned char *gat; // NULL‚Ȃ牺‚Ìmap_data_other_server‚Æ‚µ‚Ĉµ‚¤
+ char *alias; // [MouseJstr]
struct block_list **block;
struct block_list **block_mob;
int *block_count,*block_mob_count;
@@ -535,9 +601,8 @@ struct map_data_other_server {
unsigned char *gat; // NULLŒÅ’è‚É‚µ‚Ä”»’f
unsigned long ip;
unsigned int port;
+ struct map_data* map;
};
-#define read_gat(m,x,y) (map[m].gat[(x)+(y)*map[m].xs])
-#define read_gatp(m,x,y) (m->gat[(x)+(y)*m->xs])
struct flooritem_data {
struct block_list bl;
@@ -556,7 +621,7 @@ enum {
SP_USTR,SP_UAGI,SP_UVIT,SP_UINT,SP_UDEX,SP_ULUK,SP_26,SP_27, // 32-39
SP_28,SP_ATK1,SP_ATK2,SP_MATK1,SP_MATK2,SP_DEF1,SP_DEF2,SP_MDEF1, // 40-47
SP_MDEF2,SP_HIT,SP_FLEE1,SP_FLEE2,SP_CRITICAL,SP_ASPD,SP_36,SP_JOBLEVEL, // 48-55
- SP_UPPER,SP_PARTNER,SP_CART,SP_FAME,SP_UNBREAKABLE, //56-58
+ SP_UPPER,SP_PARTNER,SP_CART,SP_FAME,SP_UNBREAKABLE, //56-60
SP_CARTINFO=99, // 99
SP_BASEJOB=119, // 100+19 - celest
@@ -584,15 +649,51 @@ enum {
SP_MAGIC_DAMAGE_RETURN,SP_RANDOM_ATTACK_INCREASE,SP_ALL_STATS,SP_AGI_VIT,SP_AGI_DEX_STR,SP_PERFECT_HIDE, // 1071-1076
SP_DISGUISE,SP_CLASSCHANGE, // 1077-1078
SP_HP_DRAIN_VALUE,SP_SP_DRAIN_VALUE, // 1079-1080
-
+ SP_WEAPON_ATK,SP_WEAPON_ATK_RATE, // 1081-1082
+ SP_DELAYRATE, // 1083
+
SP_RESTART_FULL_RECORVER=2000,SP_NO_CASTCANCEL,SP_NO_SIZEFIX,SP_NO_MAGIC_DAMAGE,SP_NO_WEAPON_DAMAGE,SP_NO_GEMSTONE, // 2000-2005
- SP_NO_CASTCANCEL2,SP_INFINITE_ENDURE,SP_UNBREAKABLE_WEAPON,SP_UNBREAKABLE_ARMOR // 2006-2009
+ SP_NO_CASTCANCEL2,SP_INFINITE_ENDURE,SP_UNBREAKABLE_WEAPON,SP_UNBREAKABLE_ARMOR, SP_UNBREAKABLE_HELM, // 2006-2010
+ SP_UNBREAKABLE_SHIELD, SP_LONG_ATK_RATE, // 2011-2012
+
+ SP_CRIT_ATK_RATE, SP_CRITICAL_ADDRACE, SP_NO_REGEN, SP_ADDEFF_WHENHIT, SP_AUTOSPELL_WHENHIT, // 2013-2017
+ SP_SKILL_ATK, SP_UNSTRIPABLE, SP_ADD_DAMAGE_BY_CLASS, // 2018-2020
+ SP_SP_GAIN_VALUE, SP_IGNORE_DEF_MOB, SP_HP_LOSS_RATE, SP_ADDRACE2, SP_HP_GAIN_VALUE, // 2021-2025
+ SP_SUBSIZE, SP_DAMAGE_WHEN_UNEQUIP, SP_ADD_ITEM_HEAL_RATE, SP_LOSESP_WHEN_UNEQUIP, SP_EXP_ADDRACE, // 2026-2030
+ SP_SP_GAIN_RACE, SP_SUBRACE2, SP_ADDEFF_WHENHIT_SHORT, // 2031-2033
+ SP_UNSTRIPABLE_WEAPON,SP_UNSTRIPABLE_ARMOR,SP_UNSTRIPABLE_HELM,SP_UNSTRIPABLE_SHIELD // 2034-2037
};
enum {
LOOK_BASE,LOOK_HAIR,LOOK_WEAPON,LOOK_HEAD_BOTTOM,LOOK_HEAD_TOP,LOOK_HEAD_MID,LOOK_HAIR_COLOR,LOOK_CLOTHES_COLOR,LOOK_SHIELD,LOOK_SHOES
};
+// CELL
+#define CELL_MASK 0x0f
+#define CELL_NPC 0x80 // NPCƒZƒ‹
+#define CELL_BASILICA 0x40 // BASILICAƒZƒ‹
+#define CELL_MOONLIT 0x100
+#define CELL_REGEN 0x200
+/*
+ * map_getcell()‚ÅŽg—p‚³‚ê‚éƒtƒ‰ƒO
+ */
+typedef enum {
+ CELL_CHKWALL=0, // •Ç(ƒZƒ‹ƒ^ƒCƒv1)
+ CELL_CHKWATER, // …ê(ƒZƒ‹ƒ^ƒCƒv3)
+ CELL_CHKGROUND, // ’n–ÊáŠQ•¨(ƒZƒ‹ƒ^ƒCƒv5)
+ CELL_CHKPASS, // ’ʉ߉”\(ƒZƒ‹ƒ^ƒCƒv1,5ˆÈŠO)
+ CELL_CHKNOPASS, // ’ʉߕs‰Â(ƒZƒ‹ƒ^ƒCƒv1,5)
+ CELL_GETTYPE, // ƒZƒ‹ƒ^ƒCƒv‚ð•Ô‚·
+ CELL_CHKNPC=0x10, // ƒ^ƒbƒ`ƒ^ƒCƒv‚ÌNPC(ƒZƒ‹ƒ^ƒCƒv0x80ƒtƒ‰ƒO)
+ CELL_CHKBASILICA, // ƒoƒWƒŠƒJ(ƒZƒ‹ƒ^ƒCƒv0x40ƒtƒ‰ƒO)
+} cell_t;
+// map_setcell()‚ÅŽg—p‚³‚ê‚éƒtƒ‰ƒO
+enum {
+ CELL_SETNPC=0x10, // ƒ^ƒbƒ`ƒ^ƒCƒv‚ÌNPC‚ðƒZƒbƒg
+ CELL_SETBASILICA, // ƒoƒWƒŠƒJ‚ðƒZƒbƒg
+ CELL_CLRBASILICA, // ƒoƒWƒŠƒJ‚ðƒNƒŠƒA
+};
+
struct chat_data {
struct block_list bl;
@@ -614,6 +715,17 @@ extern int autosave_interval;
extern int agit_flag;
extern int night_flag; // 0=day, 1=night [Yor]
+// gat?Ö§
+int map_getcell(int,int,int,cell_t);
+int map_getcellp(struct map_data*,int,int,cell_t);
+void map_setcell(int,int,int,int);
+extern int map_read_flag; // 0: grf«Õ«¡«¤«ë 1: «­«ã«Ã«·«å 2: «­«ã«Ã«·«å(?õê)
+enum {
+ READ_FROM_GAT, READ_FROM_AFM,
+ READ_FROM_BITMAP, CREATE_BITMAP,
+ READ_FROM_BITMAP_COMPRESSED, CREATE_BITMAP_COMPRESSED
+};
+
extern char motd_txt[];
extern char help_txt[];
@@ -635,9 +747,11 @@ void map_foreachinarea(int (*)(struct block_list*,va_list),int,int,int,int,int,i
// -- moonsoul (added map_foreachincell)
void map_foreachincell(int (*)(struct block_list*,va_list),int,int,int,int,...);
void map_foreachinmovearea(int (*)(struct block_list*,va_list),int,int,int,int,int,int,int,int,...);
+void map_foreachinpath(int (*func)(struct block_list*,va_list),int m,int x0,int y0,int x1,int y1,int range,int type,...); // Celest
int map_countnearpc(int,int,int);
//blockŠÖ˜A‚ɒljÁ
int map_count_oncell(int m,int x,int y);
+struct skill_unit *map_find_skill_unit_oncell(struct block_list *,int x,int y,int skill_id,struct skill_unit *);
// ˆêŽž“IobjectŠÖ˜A
int map_addobject(struct block_list *);
int map_delobject(int);
@@ -659,6 +773,7 @@ void map_addchariddb(int charid,char *name);
void map_delchariddb(int charid);
int map_reqchariddb(struct map_session_data * sd,int charid);
char * map_charid2nick(int);
+struct map_session_data * map_charid2sd(int);
struct map_session_data * map_id2sd(int);
struct block_list * map_id2bl(int);
@@ -666,15 +781,13 @@ int map_mapname2mapid(char*);
int map_mapname2ipport(char*,int*,int*);
int map_setipport(char *name,unsigned long ip,int port);
int map_eraseipport(char *name,unsigned long ip,int port);
+int map_eraseallipport(void);
void map_addiddb(struct block_list *);
void map_deliddb(struct block_list *bl);
int map_foreachiddb(int (*)(void*,void*,va_list),...);
void map_addnickdb(struct map_session_data *);
struct map_session_data * map_nick2sd(char*);
-
-// gatŠÖ˜A
-int map_getcell(int,int,int);
-int map_setcell(int,int,int,int);
+int compare_item(struct item *a, struct item *b);
// ‚»‚Ì‘¼
int map_check_dir(int s_dir,int t_dir);
@@ -682,18 +795,33 @@ int map_calc_dir( struct block_list *src,int x,int y);
// path.c‚æ‚è
int path_search(struct walkpath_data*,int,int,int,int,int,int);
+int path_search_long(struct shootpath_data *,int,int,int,int,int);
int path_blownpos(int m,int x0,int y0,int dx,int dy,int count);
int map_who(int fd);
+int cleanup_sub(struct block_list *bl, va_list ap);
+
void map_helpscreen(); // [Valaris]
int map_delmap(char *mapname);
-extern unsigned long ticks;
+extern char *INTER_CONF_NAME;
+extern char *LOG_CONF_NAME;
+extern char *MAP_CONF_NAME;
+extern char *BATTLE_CONF_FILENAME;
+extern char *ATCOMMAND_CONF_FILENAME;
+extern char *CHARCOMMAND_CONF_FILENAME;
+extern char *SCRIPT_CONF_NAME;
+extern char *MSG_CONF_NAME;
+extern char *GRF_PATH_FILENAME;
#ifndef TXT_ONLY
// MySQL
+#ifdef __WIN32
+#include <my_global.h>
+#include <my_sys.h>
+#endif
#include <mysql.h>
void char_online_check(void); // [Valaris]
diff --git a/src/map/mob.c b/src/map/mob.c
index ef67341f8..f076b7530 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -13,6 +13,7 @@
#include "clif.h"
#include "intif.h"
#include "pc.h"
+#include "status.h"
#include "mob.h"
#include "guild.h"
#include "itemdb.h"
@@ -21,6 +22,7 @@
#include "party.h"
#include "npc.h"
#include "log.h"
+#include "showmsg.h"
#ifdef MEMWATCH
#include "memwatch.h"
@@ -31,7 +33,9 @@
#define MOB_LAZYMOVEPERC 50 // Move probability in the negligent mode MOB (rate of 1000 minute)
#define MOB_LAZYWARPPERC 20 // Warp probability in the negligent mode MOB (rate of 1000 minute)
-struct mob_db mob_db[2001];
+struct mob_db mob_db[MAX_MOB_DB+1];
+
+#define CLASSCHANGE_BOSS_NUM 21
/*==========================================
* Local prototype declaration (only required thing)
@@ -42,7 +46,7 @@ static int mob_makedummymobdb(int);
static int mob_timer(int,unsigned int,int,int);
int mobskill_use(struct mob_data *md,unsigned int tick,int event);
int mobskill_deltimer(struct mob_data *md );
-int mob_skillid2skillidx(int class,int skillid);
+int mob_skillid2skillidx(int class_,int skillid);
int mobskill_use_id(struct mob_data *md,struct block_list *target,int skill_idx);
static int mob_unlocktarget(struct mob_data *md,int tick);
@@ -67,7 +71,7 @@ int mobdb_searchname(const char *str)
* Id Mob is checked.
*------------------------------------------
*/
-int mobdb_checkid(const int id)
+int mobdb_checkid(const int id)
{
if (id <= 0 || id >= (sizeof(mob_db) / sizeof(mob_db[0])) || mob_db[id].name[0] == '\0')
return 0;
@@ -79,28 +83,28 @@ int mobdb_checkid(const int id)
* The minimum data set for MOB spawning
*------------------------------------------
*/
-int mob_spawn_dataset(struct mob_data *md,const char *mobname,int class)
+int mob_spawn_dataset(struct mob_data *md,const char *mobname,int class_)
{
nullpo_retr(0, md);
md->bl.prev=NULL;
md->bl.next=NULL;
if(strcmp(mobname,"--en--")==0)
- memcpy(md->name,mob_db[class].name,24);
+ memcpy(md->name,mob_db[class_].name,24);
else if(strcmp(mobname,"--ja--")==0)
- memcpy(md->name,mob_db[class].jname,24);
+ memcpy(md->name,mob_db[class_].jname,24);
else
memcpy(md->name,mobname,24);
md->n = 0;
- md->base_class = md->class = class;
+ md->base_class = md->class_ = class_;
md->bl.id= npc_get_new_npc_id();
memset(&md->state,0,sizeof(md->state));
md->timer = -1;
md->target_id=0;
md->attacked_id=0;
- md->speed=mob_db[class].speed;
+ md->speed=mob_db[class_].speed;
return 0;
}
@@ -110,97 +114,108 @@ int mob_spawn_dataset(struct mob_data *md,const char *mobname,int class)
* The MOB appearance for one time (for scripts)
*------------------------------------------
*/
-int mob_once_spawn(struct map_session_data *sd,char *mapname,
- int x,int y,const char *mobname,int class,int amount,const char *event)
+int mob_once_spawn (struct map_session_data *sd, char *mapname,
+ int x, int y, const char *mobname, int class_, int amount, const char *event)
{
- struct mob_data *md=NULL;
- int m,count,lv=255,r=class;
-
- if( sd )
- lv=sd->status.base_level;
+ struct mob_data *md = NULL;
+ int m, count, lv = 255;
+ int i, j;
+
+ if(sd) lv = sd->status.base_level;
- if( sd && strcmp(mapname,"this")==0)
- m=sd->bl.m;
+ if(sd && strcmp(mapname,"this")==0)
+ m = sd->bl.m;
else
- m=map_mapname2mapid(mapname);
+ m = map_mapname2mapid(mapname);
- if(m<0 || amount<=0 || (class>=0 && class<=1000) || class>6000) // ’l‚ªˆÙí‚Ȃ碊«‚ðŽ~‚ß‚é
+ if (m < 0 || amount <= 0 || (class_ >= 0 && class_ <= 1000) || class_ > MAX_MOB_DB + 4000) // ’l‚ªˆÙí‚Ȃ碊«‚ðŽ~‚ß‚é
return 0;
- if(class<0){ // ƒ‰ƒ“ƒ_ƒ€‚ɢЫ
- int i=0;
- int j=-class-1;
+ if (class_ < 0) { // ƒ‰ƒ“ƒ_ƒ€‚ɢЫ
int k;
- if(j>=0 && j<MAX_RANDOMMONSTER){
- do{
- class=rand()%1000+1001;
- k=rand()%1000000;
- }while((mob_db[class].max_hp <= 0 || mob_db[class].summonper[j] <= k ||
- (lv<mob_db[class].lv && battle_config.random_monster_checklv)) && (i++) < 2000);
- if(i>=2000){
- class=mob_db[0].summonper[j];
- }
- }else{
+ i = 0;
+ j = -class_-1;
+ if(j >= 0 && j < MAX_RANDOMMONSTER) {
+ do {
+ class_ = rand() % 1000 + 1001;
+ k = rand() % 1000000;
+ } while ((mob_db[class_].max_hp <= 0 || mob_db[class_].summonper[j] <= k ||
+ (battle_config.random_monster_checklv && lv < mob_db[class_].lv)) && (i++) < 2000);
+ if(i >= 2000)
+ class_ = mob_db[0].summonper[j];
+ } else
return 0;
- }
// if(battle_config.etc_log)
-// printf("mobclass=%d try=%d\n",class,i);
+// printf("mobclass=%d try=%d\n",class_,i);
}
- if(sd){
- if(x<=0) x=sd->bl.x;
- if(y<=0) y=sd->bl.y;
- }else if(x<=0 || y<=0){
- printf("mob_once_spawn: ??\n");
+ if (sd) { //even if the coords were wrong, spawn mob anyways (but look for most suitable coords first) Got from Freya [Lupus]
+ if (x <= 0 || y <= 0) {
+ if (x <= 0) x = sd->bl.x + rand() % 3 - 1;
+ if (y <= 0) y = sd->bl.y + rand() % 3 - 1;
+ if (map_getcell(m, x, y, CELL_CHKNOPASS)) {
+ x = sd->bl.x;
+ y = sd->bl.y;
+ }
+ }
+ } else if (x <= 0 || y <= 0) {
+ i = j = 0;
+ printf("mob_once_spawn: %i at %s x:%i y:%i\n ??\n",class_,map[m].name,x,y); //got idea from Freya [Lupus]
+ do {
+ x = rand() % (map[m].xs - 2) + 1;
+ y = rand() % (map[m].ys - 2) + 1;
+ } while ((i = map_getcell(m, x, y, CELL_CHKNOPASS)) && j++ < 64);
+ if (i) { // not solved?
+ x = 0;
+ y = 0;
+ }
}
- for(count=0;count<amount;count++){
- md=(struct mob_data *)aCalloc(1,sizeof(struct mob_data));
- memset(md, '\0', sizeof *md);
+ for (count = 0; count < amount; count++) {
+ md = (struct mob_data *)aCalloc(1,sizeof(struct mob_data));
+ memset (md, '\0', sizeof *md);
- if(class>4000) { // large/tiny mobs [Valaris]
- md->size=2;
- class-=4000;
- }
- else if(class>2000) {
- md->size=1;
- class-=2000;
+ if (class_ > MAX_MOB_DB + 2000) { // large/tiny mobs [Valaris]
+ md->size = 2;
+ class_ -= (MAX_MOB_DB + 2000);
+ } else if (class_ > MAX_MOB_DB) {
+ md->size = 1;
+ class_ -= MAX_MOB_DB;
}
- if(mob_db[class].mode&0x02)
- md->lootitem=(struct item *)aCalloc(LOOTITEM_SIZE,sizeof(struct item));
+ if(mob_db[class_].mode & 0x02)
+ md->lootitem = (struct item *)aCalloc(LOOTITEM_SIZE,sizeof(struct item));
else
- md->lootitem=NULL;
-
- mob_spawn_dataset(md,mobname,class);
- md->bl.m=m;
- md->bl.x=x;
- md->bl.y=y;
- if(r<0&&battle_config.dead_branch_active) md->mode=0x1+0x4+0x80; //ˆÚ“®‚µ‚ăAƒNƒeƒBƒu‚Å”½Œ‚‚·‚é
- md->m =m;
- md->x0=x;
- md->y0=y;
- md->xs=0;
- md->ys=0;
- md->spawndelay1=-1; // ˆê“x‚̂݃tƒ‰ƒO
- md->spawndelay2=-1; // ˆê“x‚̂݃tƒ‰ƒO
+ md->lootitem = NULL;
- memcpy(md->npc_event,event,sizeof(md->npc_event));
-
- md->bl.type=BL_MOB;
- map_addiddb(&md->bl);
- mob_spawn(md->bl.id);
-
- if(class==1288) { // emperium hp based on defense level [Valaris]
- struct guild_castle *gc=guild_mapname2gc(map[md->bl.m].name);
+ mob_spawn_dataset (md, mobname, class_);
+ md->bl.m = m;
+ md->bl.x = x;
+ md->bl.y = y;
+ if (class_ < 0 && battle_config.dead_branch_active)
+ md->mode = 0x1 + 0x4 + 0x80; //ˆÚ“®‚µ‚ăAƒNƒeƒBƒu‚Å”½Œ‚‚·‚é
+ md->m = m;
+ md->x0 = x;
+ md->y0 = y;
+ //md->xs = 0;
+ //md->ys = 0;
+ md->spawndelay1 = -1; // ˆê“x‚̂݃tƒ‰ƒO
+ md->spawndelay2 = -1; // ˆê“x‚̂݃tƒ‰ƒO
+
+ memcpy(md->npc_event, event, strlen(event));
+
+ md->bl.type = BL_MOB;
+ map_addiddb (&md->bl);
+ mob_spawn (md->bl.id);
+
+ if(class_ == 1288) { // emperium hp based on defense level [Valaris]
+ struct guild_castle *gc = guild_mapname2gc(map[md->bl.m].name);
if(gc) {
- mob_db[class].max_hp+=2000*gc->defense;
- md->hp=mob_db[class].max_hp;
+ mob_db[class_].max_hp += 2000 * gc->defense;
+ md->hp = mob_db[class_].max_hp;
}
} // end addition [Valaris]
-
-
}
- return (amount>0)?md->bl.id:0;
+ return (amount > 0) ? md->bl.id : 0;
}
/*==========================================
* The MOB appearance for one time (& area specification for scripts)
@@ -208,9 +223,9 @@ int mob_once_spawn(struct map_session_data *sd,char *mapname,
*/
int mob_once_spawn_area(struct map_session_data *sd,char *mapname,
int x0,int y0,int x1,int y1,
- const char *mobname,int class,int amount,const char *event)
+ const char *mobname,int class_,int amount,const char *event)
{
- int x,y,i,c,max,lx=-1,ly=-1,id=0;
+ int x,y,i,max,lx=-1,ly=-1,id=0;
int m;
if(strcmp(mapname,"this")==0)
@@ -221,7 +236,7 @@ int mob_once_spawn_area(struct map_session_data *sd,char *mapname,
max=(y1-y0+1)*(x1-x0+1)*3;
if(max>1000)max=1000;
- if(m<0 || amount<=0 || (class>=0 && class<=1000) || class>6000) // A summon is stopped if a value is unusual
+ if(m<0 || amount<=0 || (class_>=0 && class_<=1000) || class_>MAX_MOB_DB) // A summon is stopped if a value is unusual
return 0;
for(i=0;i<amount;i++){
@@ -229,15 +244,17 @@ int mob_once_spawn_area(struct map_session_data *sd,char *mapname,
do{
x=rand()%(x1-x0+1)+x0;
y=rand()%(y1-y0+1)+y0;
- }while( ( (c=map_getcell(m,x,y))==1 || c==5)&& (++j)<max );
+ } while (map_getcell(m,x,y,CELL_CHKNOPASS) && (++j)<max);
+ // freya }while( ( (c=map_getcell(m,x,y))==1 || c==5)&& (++j)<max );
if(j>=max){
- if(lx>=0){ // ŒŸõ‚ÉŽ¸”s‚µ‚½‚̂ňȑO‚É•¦‚¢‚½êŠ‚ðŽg‚¤
+ if(lx>=0){ // Since reference went wrong, the place which boiled before is used.
x=lx;
y=ly;
}else
- return 0; // ʼn‚É•¦‚­êŠ‚ÌŒŸõ‚ðŽ¸”s‚µ‚½‚̂łâ‚ß‚é
+ return 0; // Since reference of the place which boils first went wrong, it stops.
}
- id=mob_once_spawn(sd,mapname,x,y,mobname,class,1,event);
+ if(x==0||y==0) printf("xory=0, x=%d,y=%d,x0=%d,y0=%d\n",x,y,x0,y0);
+ id=mob_once_spawn(sd,mapname,x,y,mobname,class_,1,event);
lx=x;
ly=y;
}
@@ -249,7 +266,7 @@ int mob_once_spawn_area(struct map_session_data *sd,char *mapname,
*------------------------------------------
*/
int mob_spawn_guardian(struct map_session_data *sd,char *mapname,
- int x,int y,const char *mobname,int class,int amount,const char *event,int guardian)
+ int x,int y,const char *mobname,int class_,int amount,const char *event,int guardian)
{
struct mob_data *md=NULL;
int m,count=1,lv=255;
@@ -262,33 +279,27 @@ int mob_spawn_guardian(struct map_session_data *sd,char *mapname,
else
m=map_mapname2mapid(mapname);
- if(m<0 || amount<=0 || (class>=0 && class<=1000) || class>2000) // ’l‚ªˆÙí‚Ȃ碊«‚ðŽ~‚ß‚é
+ if(m<0 || amount<=0 || (class_>=0 && class_<=1000) || class_>MAX_MOB_DB) // Invalid monster classes
return 0;
- if(class<0)
+ if(class_<0)
return 0;
-
+
if(sd){
if(x<=0) x=sd->bl.x;
if(y<=0) y=sd->bl.y;
}
-
+
else if(x<=0 || y<=0)
printf("mob_spawn_guardian: ??\n");
-
+
for(count=0;count<amount;count++){
struct guild_castle *gc;
- md=calloc(sizeof(struct mob_data), 1);
- if(md==NULL){
- printf("mob_spawn_guardian: out of memory !\n");
- exit(1);
- }
+ md=(struct mob_data *) aCalloc(sizeof(struct mob_data), 1);
memset(md, '\0', sizeof *md);
-
-
- mob_spawn_dataset(md,mobname,class);
+ mob_spawn_dataset(md,mobname,class_);
md->bl.m=m;
md->bl.x=x;
md->bl.y=y;
@@ -308,7 +319,7 @@ int mob_spawn_guardian(struct map_session_data *sd,char *mapname,
gc=guild_mapname2gc(map[md->bl.m].name);
if(gc) {
- mob_db[class].max_hp+=2000*gc->defense;
+ mob_db[class_].max_hp+=2000*gc->defense;
if(guardian==0) { md->hp=gc->Ghp0; gc->GID0=md->bl.id; }
if(guardian==1) { md->hp=gc->Ghp1; gc->GID1=md->bl.id; }
if(guardian==2) { md->hp=gc->Ghp2; gc->GID2=md->bl.id; }
@@ -317,7 +328,6 @@ int mob_spawn_guardian(struct map_session_data *sd,char *mapname,
if(guardian==5) { md->hp=gc->Ghp5; gc->GID5=md->bl.id; }
if(guardian==6) { md->hp=gc->Ghp6; gc->GID6=md->bl.id; }
if(guardian==7) { md->hp=gc->Ghp7; gc->GID7=md->bl.id; }
-
}
}
@@ -366,49 +376,49 @@ int mob_exclusion_check(struct mob_data *md,struct map_session_data *sd)
* Appearance income of mob
*------------------------------------------
*/
-int mob_get_viewclass(int class)
+int mob_get_viewclass(int class_)
{
- return mob_db[class].view_class;
+ return mob_db[class_].view_class;
}
-int mob_get_sex(int class)
+int mob_get_sex(int class_)
{
- return mob_db[class].sex;
+ return mob_db[class_].sex;
}
-short mob_get_hair(int class)
+short mob_get_hair(int class_)
{
- return mob_db[class].hair;
+ return mob_db[class_].hair;
}
-short mob_get_hair_color(int class)
+short mob_get_hair_color(int class_)
{
- return mob_db[class].hair_color;
+ return mob_db[class_].hair_color;
}
-short mob_get_weapon(int class)
+short mob_get_weapon(int class_)
{
- return mob_db[class].weapon;
+ return mob_db[class_].weapon;
}
-short mob_get_shield(int class)
+short mob_get_shield(int class_)
{
- return mob_db[class].shield;
+ return mob_db[class_].shield;
}
-short mob_get_head_top(int class)
+short mob_get_head_top(int class_)
{
- return mob_db[class].head_top;
+ return mob_db[class_].head_top;
}
-short mob_get_head_mid(int class)
+short mob_get_head_mid(int class_)
{
- return mob_db[class].head_mid;
+ return mob_db[class_].head_mid;
}
-short mob_get_head_buttom(int class)
+short mob_get_head_buttom(int class_)
{
- return mob_db[class].head_buttom;
+ return mob_db[class_].head_buttom;
}
-short mob_get_clothes_color(int class) // Add for player monster dye - Valaris
+short mob_get_clothes_color(int class_) // Add for player monster dye - Valaris
{
- return mob_db[class].clothes_color; // End
+ return mob_db[class_].clothes_color; // End
}
-int mob_get_equip(int class) // mob equip [Valaris]
+int mob_get_equip(int class_) // mob equip [Valaris]
{
- return mob_db[class].equip;
+ return mob_db[class_].equip;
}
/*==========================================
* Is MOB in the state in which the present movement is possible or not?
@@ -425,7 +435,7 @@ int mob_can_move(struct mob_data *md)
md->sc_data[SC_AUTOCOUNTER].timer != -1 || //ƒI[ƒgƒJƒEƒ“ƒ^[
md->sc_data[SC_BLADESTOP].timer != -1 || //”’nŽæ‚è
md->sc_data[SC_SPIDERWEB].timer != -1 //ƒXƒpƒCƒ_[ƒEƒFƒbƒu
- )
+ )
return 0;
return 1;
@@ -442,8 +452,8 @@ static int calc_next_walk_step(struct mob_data *md)
if(md->walkpath.path_pos>=md->walkpath.path_len)
return -1;
if(md->walkpath.path[md->walkpath.path_pos]&1)
- return battle_get_speed(&md->bl)*14/10;
- return battle_get_speed(&md->bl);
+ return status_get_speed(&md->bl)*14/10;
+ return status_get_speed(&md->bl);
}
static int mob_walktoxy_sub(struct mob_data *md);
@@ -455,7 +465,7 @@ static int mob_walktoxy_sub(struct mob_data *md);
static int mob_walk(struct mob_data *md,unsigned int tick,int data)
{
int moveblock;
- int i,ctype;
+ int i;
static int dirx[8]={0,-1,-1,-1,0,1,1,1};
static int diry[8]={1,1,0,-1,-1,-1,0,1};
int x,y,dx,dy;
@@ -480,8 +490,7 @@ static int mob_walk(struct mob_data *md,unsigned int tick,int data)
x = md->bl.x;
y = md->bl.y;
- ctype = map_getcell(md->bl.m,x,y);
- if(ctype == 1 || ctype == 5) {
+ if(map_getcell(md->bl.m,x,y,CELL_CHKNOPASS)) {
mob_stop_walking(md,1);
return 0;
}
@@ -489,12 +498,20 @@ static int mob_walk(struct mob_data *md,unsigned int tick,int data)
dx = dirx[md->dir];
dy = diry[md->dir];
- ctype = map_getcell(md->bl.m,x+dx,y+dy);
- if(ctype == 1 || ctype == 5) {
+ if (map_getcell(md->bl.m,x+dx,y+dy,CELL_CHKBASILICA) && !(status_get_mode(&md->bl)&0x20)) {
+ mob_stop_walking(md,1);
+ return 0;
+ }
+
+ if (map_getcell(md->bl.m,x+dx,y+dy,CELL_CHKNOPASS)) {
mob_walktoxy_sub(md);
return 0;
}
+ if (skill_check_moonlit (&md->bl,x+dx,y+dy)) {
+ mob_walktoxy_sub(md);
+ return 0;
+ }
moveblock = ( x/BLOCK_SIZE != (x+dx)/BLOCK_SIZE || y/BLOCK_SIZE != (y+dy)/BLOCK_SIZE);
md->state.state=MS_WALK;
@@ -505,18 +522,18 @@ static int mob_walk(struct mob_data *md,unsigned int tick,int data)
if(md->min_chase>13)
md->min_chase--;
+ skill_unit_move(&md->bl,tick,0);
if(moveblock) map_delblock(&md->bl);
md->bl.x = x;
md->bl.y = y;
if(moveblock) map_addblock(&md->bl);
+ skill_unit_move(&md->bl,tick,1);
map_foreachinmovearea(clif_mobinsight,md->bl.m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,-dx,-dy,BL_PC,md);
md->state.state=MS_IDLE;
if(md->option&4)
skill_check_cloaking(&md->bl);
-
- skill_unit_move(&md->bl,tick,1); // ƒXƒLƒ‹ƒ†ƒjƒbƒg‚ÌŒŸ¸
}
if((i=calc_next_walk_step(md))>0){
i = i>>1;
@@ -591,11 +608,11 @@ static int mob_attack(struct mob_data *md,unsigned int tick,int data)
if(!md->mode)
- mode=mob_db[md->class].mode;
+ mode=mob_db[md->class_].mode;
else
mode=md->mode;
- race=mob_db[md->class].race;
+ race=mob_db[md->class_].race;
if(!(mode&0x80)){
md->target_id=0;
md->state.targettype = NONE_ATTACKABLE;
@@ -604,11 +621,11 @@ static int mob_attack(struct mob_data *md,unsigned int tick,int data)
if(tsd && !(mode&0x20) && (tsd->sc_data[SC_TRICKDEAD].timer != -1 || tsd->sc_data[SC_BASILICA].timer != -1 ||
((pc_ishiding(tsd) || tsd->state.gangsterparadise) && !((race == 4 || race == 6) && !tsd->perfect_hiding) ) ) ) {
md->target_id=0;
- md->state.targettype = NONE_ATTACKABLE;
+ md->state.targettype = NONE_ATTACKABLE;
return 0;
}
- range = mob_db[md->class].range;
+ range = mob_db[md->class_].range;
if(mode&1)
range++;
if(distance(md->bl.x,md->bl.y,tbl->x,tbl->y) > range)
@@ -625,9 +642,9 @@ static int mob_attack(struct mob_data *md,unsigned int tick,int data)
md->target_lv = battle_weapon_attack(&md->bl,tbl,tick,0);
if(!(battle_config.monster_cloak_check_type&2) && md->sc_data[SC_CLOAKING].timer != -1)
- skill_status_change_end(&md->bl,SC_CLOAKING,-1);
+ status_change_end(&md->bl,SC_CLOAKING,-1);
- md->attackabletime = tick + battle_get_adelay(&md->bl);
+ md->attackabletime = tick + status_get_adelay(&md->bl);
md->timer=add_timer(md->attackabletime,mob_timer,md->bl.id,0);
md->state.state=MS_ATTACK;
@@ -684,7 +701,7 @@ int mob_changestate(struct mob_data *md,int state,int type)
if(i>0 && i<2000)
md->timer=add_timer(md->attackabletime,mob_timer,md->bl.id,0);
else if(type) {
- md->attackabletime = tick + battle_get_amotion(&md->bl);
+ md->attackabletime = tick + status_get_amotion(&md->bl);
md->timer=add_timer(md->attackabletime,mob_timer,md->bl.id,0);
}
else {
@@ -702,8 +719,8 @@ int mob_changestate(struct mob_data *md,int state,int type)
md->last_deadtime=gettick();
// Since it died, all aggressors' attack to this mob is stopped.
clif_foreachclient(mob_stopattacked,md->bl.id);
- skill_unit_out_all(&md->bl,gettick(),1);
- skill_status_change_clear(&md->bl,2); // ƒXƒe[ƒ^ƒXˆÙí‚ð‰ðœ‚·‚é
+ skill_unit_move(&md->bl,gettick(),0);
+ status_change_clear(&md->bl,2); // ƒXƒe[ƒ^ƒXˆÙí‚ð‰ðœ‚·‚é
skill_clear_unitgroup(&md->bl); // ‘S‚ẴXƒLƒ‹ƒ†ƒjƒbƒgƒOƒ‹[ƒv‚ð휂·‚é
skill_cleartimerskill(&md->bl);
if(md->deletetimer!=-1)
@@ -730,15 +747,12 @@ static int mob_timer(int tid,unsigned int tick,int id,int data)
if( (bl=map_id2bl(id)) == NULL ){ //UŒ‚‚µ‚Ä‚«‚½“G‚ª‚à‚¤‚¢‚È‚¢‚̂ͳí‚̂悤‚¾
return 1;
}
-
+
if(!bl || !bl->type || bl->type!=BL_MOB)
return 1;
nullpo_retr(1, md=(struct mob_data*)bl);
- if(!md->bl.type || md->bl.type!=BL_MOB)
- return 1;
-
if(md->timer != tid){
if(battle_config.error_log)
printf("mob_timer %d != %d\n",md->timer,tid);
@@ -764,6 +778,10 @@ static int mob_timer(int tid,unsigned int tick,int id,int data)
printf("mob_timer : %d ?\n",md->state.state);
break;
}
+
+ if (md->timer == -1)
+ mob_changestate(md,MS_WALK,0);
+
map_freeblock_unlock();
return 0;
}
@@ -775,11 +793,25 @@ static int mob_timer(int tid,unsigned int tick,int id,int data)
static int mob_walktoxy_sub(struct mob_data *md)
{
struct walkpath_data wpd;
+ int x,y;
+ static int dirx[8]={0,-1,-1,-1,0,1,1,1};
+ static int diry[8]={1,1,0,-1,-1,-1,0,1};
nullpo_retr(0, md);
+ memset(&wpd, 0, sizeof(wpd));
+
if(path_search(&wpd,md->bl.m,md->bl.x,md->bl.y,md->to_x,md->to_y,md->state.walk_easy))
return 1;
+ if (wpd.path[0] >= 8)
+ return 1;
+ x = md->bl.x+dirx[wpd.path[0]];
+ y = md->bl.y+diry[wpd.path[0]];
+ if (map_getcell(md->bl.m,x,y,CELL_CHKBASILICA) && !(status_get_mode(&md->bl)&0x20)) {
+ md->state.change_walk_target=0;
+ return 1;
+ }
+
memcpy(&md->walkpath,&wpd,sizeof(wpd));
md->state.change_walk_target=0;
@@ -857,7 +889,7 @@ int mob_setdelayspawn(int id)
spawntime1=md->last_spawntime+md->spawndelay1;
spawntime2=md->last_deadtime+md->spawndelay2;
- spawntime3=gettick()+5000;
+ spawntime3=gettick()+5000+rand()%5000; //Lupus
// spawntime = max(spawntime1,spawntime2,spawntime3);
if(DIFF_TICK(spawntime1,spawntime2)>0)
spawntime=spawntime1;
@@ -882,7 +914,8 @@ int mob_spawn(int id)
struct mob_data *md;
struct block_list *bl;
- nullpo_retr(-1, bl=map_id2bl(id));
+ //nullpo_retr(-1, bl=map_id2bl(id));
+ bl=map_id2bl(id);
if(!bl || !bl->type || bl->type!=BL_MOB)
return -1;
@@ -891,15 +924,15 @@ int mob_spawn(int id)
if(!md || !md->bl.type || md->bl.type!=BL_MOB)
return -1;
-
+
md->last_spawntime=tick;
if( md->bl.prev!=NULL ){
// clif_clearchar_area(&md->bl,3);
- skill_unit_out_all(&md->bl,gettick(),1);
+// skill_unit_move(&md->bl,tick,0);
map_delblock(&md->bl);
}
else
- md->class = md->base_class;
+ md->class_ = md->base_class;
md->bl.m =md->m;
do {
@@ -911,7 +944,7 @@ int mob_spawn(int id)
y=md->y0+rand()%(md->ys+1)-md->ys/2;
}
i++;
- } while(((c=map_getcell(md->bl.m,x,y))==1 || c==5) && i<50);
+ } while(map_getcell(md->bl.m,x,y,CELL_CHKNOPASS) && i<50);
if(i>=50){
// if(battle_config.error_log==1)
@@ -923,8 +956,7 @@ int mob_spawn(int id)
md->to_x=md->bl.x=x;
md->to_y=md->bl.y=y;
md->dir=0;
-
- map_addblock(&md->bl);
+ md->target_dir=0;
memset(&md->state,0,sizeof(md->state));
md->attacked_id = 0;
@@ -932,11 +964,11 @@ int mob_spawn(int id)
md->move_fail_count = 0;
if(!md->speed)
- md->speed = mob_db[md->class].speed;
- md->def_ele = mob_db[md->class].element;
+ md->speed = mob_db[md->class_].speed;
+ md->def_ele = mob_db[md->class_].element;
if(!md->level) // [Valaris]
- md->level=mob_db[md->class].lv;
+ md->level=mob_db[md->class_].lv;
md->master_id=0;
md->master_dist=0;
@@ -950,13 +982,12 @@ int mob_spawn(int id)
md->canmove_tick = tick;
md->guild_id = 0;
- if (md->class >= 1285 && md->class <= 1288) {
+ if (md->class_ >= 1285 && md->class_ <= 1288) {
struct guild_castle *gc=guild_mapname2gc(map[md->bl.m].name);
if(gc)
md->guild_id = gc->guild_id;
}
-
- md->sg_count=0;
+
md->deletetimer=-1;
md->skilltimer=-1;
@@ -983,12 +1014,15 @@ int mob_spawn(int id)
memset(md->skillunit,0,sizeof(md->skillunit));
memset(md->skillunittick,0,sizeof(md->skillunittick));
- md->hp = battle_get_max_hp(&md->bl);
+ md->hp = status_get_max_hp(&md->bl);
if(md->hp<=0){
- mob_makedummymobdb(md->class);
- md->hp = battle_get_max_hp(&md->bl);
+ mob_makedummymobdb(md->class_);
+ md->hp = status_get_max_hp(&md->bl);
}
+ map_addblock(&md->bl);
+ skill_unit_move(&md->bl,tick,1);
+
clif_spawnmob(md);
return 0;
@@ -1026,10 +1060,9 @@ int mob_stop_walking(struct mob_data *md,int type)
{
nullpo_retr(0, md);
-
if(md->state.state == MS_WALK || md->state.state == MS_IDLE) {
int dx=0,dy=0;
-
+
md->walkpath.path_len=0;
if(type&4){
dx=md->to_x-md->bl.x;
@@ -1054,9 +1087,9 @@ int mob_stop_walking(struct mob_data *md,int type)
if(type&0x01)
clif_fixmobpos(md);
if(type&0x02) {
- int delay=battle_get_dmotion(&md->bl);
+ int delay=status_get_dmotion(&md->bl);
unsigned int tick = gettick();
- if(md->canmove_tick < tick)
+ if(battle_config.monster_damage_delay && md->canmove_tick < tick)
md->canmove_tick = tick + delay;
}
@@ -1079,46 +1112,43 @@ int mob_can_reach(struct mob_data *md,struct block_list *bl,int range)
dx=abs(bl->x - md->bl.x);
dy=abs(bl->y - md->bl.y);
+ if( md->bl.m != bl->m) // ˆá‚¤ƒƒbƒv
+ return 0;
+
+ if( range>0 && range < ((dx>dy)?dx:dy) ) // ‰“‚·‚¬‚é
+ return 0;
+
+ if( md->bl.x==bl->x && md->bl.y==bl->y ) // “¯‚¶ƒ}ƒX
+ return 1;
+
//=========== guildcastle guardian no search start===========
//when players are the guild castle member not attack them !
- if(md->class >= 1285 && md->class <= 1287){
+ /*if(md->class_ >= 1285 && md->class_ <= 1287){
struct map_session_data *sd;
struct guild *g=NULL;
struct guild_castle *gc=guild_mapname2gc(map[bl->m].name);
if(gc && agit_flag==0) // Guardians will not attack during non-woe time [Valaris]
return 0; // end addition [Valaris]
-
- if(bl && bl->type == BL_PC){
+
+ if(gc && bl->type == BL_PC){
nullpo_retr(0, sd=(struct map_session_data *)bl);
- if(!gc)
- return 0;
- if(gc && sd && sd->status.guild_id) {
- g=guild_search(sd->status.guild_id); // don't attack guild members [Valaris]
+ if(gc && sd->status.guild_id > 0) {
+ g=guild_search(sd->status.guild_id); // don't attack guild members [Valaris]
if(g && g->guild_id == gc->guild_id)
return 0;
if(g && gc && guild_isallied(g,gc))
return 0;
-
}
}
- }
+ }*/
//========== guildcastle guardian no search eof==============
- if(bl && bl->type == BL_PC && battle_config.monsters_ignore_gm) { // option to have monsters ignore GMs [Valaris]
+ /*if(bl->type == BL_PC && battle_config.monsters_ignore_gm) { // option to have monsters ignore GMs [Valaris]
struct map_session_data *sd;
if((sd=(struct map_session_data *)bl) != NULL && pc_isGM(sd) >= battle_config.monsters_ignore_gm)
return 0;
- }
-
- if( md->bl.m != bl->m) // ˆá‚¤ƒƒbƒv
- return 0;
-
- if( range>0 && range < ((dx>dy)?dx:dy) ) // ‰“‚·‚¬‚é
- return 0;
-
- if( md->bl.x==bl->x && md->bl.y==bl->y ) // “¯‚¶ƒ}ƒX
- return 1;
+ }*/
// Obstacle judging
wpd.path_len=0;
@@ -1156,12 +1186,12 @@ int mob_target(struct mob_data *md,struct block_list *bl,int dist)
nullpo_retr(0, md);
nullpo_retr(0, bl);
- sc_data = battle_get_sc_data(bl);
- option = battle_get_option(bl);
- race=mob_db[md->class].race;
+ sc_data = status_get_sc_data(bl);
+ option = status_get_option(bl);
+ race=mob_db[md->class_].race;
if(!md->mode)
- mode=mob_db[md->class].mode;
+ mode=mob_db[md->class_].mode;
else
mode=md->mode;
@@ -1170,7 +1200,9 @@ int mob_target(struct mob_data *md,struct block_list *bl,int dist)
return 0;
}
// Nothing will be carried out if there is no mind of changing TAGE by TAGE ending.
- if( (md->target_id > 0 && md->state.targettype == ATTACKABLE) && ( !(mode&0x04) || rand()%100>25) )
+ if( (md->target_id > 0 && md->state.targettype == ATTACKABLE) && (!(mode&0x04) || rand()%100>25) &&
+ // if the monster was provoked ignore the above rule [celest]
+ !(md->state.provoke_flag && md->state.provoke_flag == bl->id))
return 0;
if(mode&0x20 || // Coercion is exerted if it is MVPMOB.
@@ -1184,11 +1216,13 @@ int mob_target(struct mob_data *md,struct block_list *bl,int dist)
return 0;
}
- md->target_id=bl->id; // Since there was no disturbance, it locks on to target.
+ md->target_id = bl->id; // Since there was no disturbance, it locks on to target.
if(bl->type == BL_PC || bl->type == BL_MOB)
md->state.targettype = ATTACKABLE;
else
md->state.targettype = NONE_ATTACKABLE;
+ if (md->state.provoke_flag)
+ md->state.provoke_flag = 0;
md->min_chase=dist+13;
if(md->min_chase>26)
md->min_chase=26;
@@ -1223,18 +1257,18 @@ static int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap)
return 0;
if(!smd->mode)
- mode=mob_db[smd->class].mode;
+ mode=mob_db[smd->class_].mode;
else
mode=smd->mode;
// ƒAƒNƒeƒBƒu‚Ń^[ƒQƒbƒgŽË’ö“à‚É‚¢‚é‚È‚çAƒƒbƒN‚·‚é
if( mode&0x04 ){
- race=mob_db[smd->class].race;
+ race=mob_db[smd->class_].race;
//‘ÎÛ‚ªPC‚Ìê‡
if(tsd &&
- !pc_isdead(tsd) &&
- tsd->bl.m == smd->bl.m &&
- tsd->invincible_timer == -1 &&
+ !pc_isdead(tsd) &&
+ tsd->bl.m == smd->bl.m &&
+ tsd->invincible_timer == -1 &&
!pc_isinvisible(tsd) &&
(dist=distance(smd->bl.x,smd->bl.y,tsd->bl.x,tsd->bl.y))<9
)
@@ -1246,7 +1280,7 @@ static int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap)
rand()%1000<1000/(++(*pcc)) ){ // ”͈͓àPC‚Å“™Šm—¦‚É‚·‚é
smd->target_id=tsd->bl.id;
smd->state.targettype = ATTACKABLE;
- smd->min_chase=13;
+ smd->min_chase=13;
}
}
}
@@ -1282,10 +1316,10 @@ static int mob_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap)
nullpo_retr(0, itc=va_arg(ap,int *));
if(!md->mode)
- mode=mob_db[md->class].mode;
+ mode=mob_db[md->class_].mode;
else
mode=md->mode;
-
+
if( !md->target_id && mode&0x02){
if(!md->lootitem || (battle_config.monster_loot_type == 1 && md->lootitem_count >= LOOTITEM_SIZE) )
@@ -1319,8 +1353,8 @@ static int mob_ai_sub_hard_linksearch(struct block_list *bl,va_list ap)
nullpo_retr(0, target=va_arg(ap,struct block_list *));
// same family free in a range at a link monster -- it will be made to lock if MOB is
-/* if( (md->target_id > 0 && md->state.targettype == ATTACKABLE) && mob_db[md->class].mode&0x08){
- if( tmd->class==md->class && (!tmd->target_id || md->state.targettype == NONE_ATTACKABLE) && tmd->bl.m == md->bl.m){
+/* if( (md->target_id > 0 && md->state.targettype == ATTACKABLE) && mob_db[md->class_].mode&0x08){
+ if( tmd->class_==md->class_ && (!tmd->target_id || md->state.targettype == NONE_ATTACKABLE) && tmd->bl.m == md->bl.m){
if( mob_can_reach(tmd,target,12) ){ // Reachability judging
tmd->target_id=md->target_id;
tmd->state.targettype = ATTACKABLE;
@@ -1328,8 +1362,8 @@ static int mob_ai_sub_hard_linksearch(struct block_list *bl,va_list ap)
}
}
}*/
- if( md->attacked_id > 0 && mob_db[md->class].mode&0x08){
- if( tmd->class==md->class && tmd->bl.m == md->bl.m && (!tmd->target_id || md->state.targettype == NONE_ATTACKABLE)){
+ if( md->attacked_id > 0 && mob_db[md->class_].mode&0x08){
+ if( tmd->class_==md->class_ && tmd->bl.m == md->bl.m && (!tmd->target_id || md->state.targettype == NONE_ATTACKABLE)){
if( mob_can_reach(tmd,target,12) ){ // Reachability judging
tmd->target_id=md->attacked_id;
tmd->state.targettype = ATTACKABLE;
@@ -1355,12 +1389,24 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick)
if((bl=map_id2bl(md->master_id)) != NULL )
mmd=(struct mob_data *)bl;
- mode=mob_db[md->class].mode;
+ mode=mob_db[md->class_].mode;
// It is not main monster/leader.
if(!mmd || mmd->bl.type!=BL_MOB || mmd->bl.id!=md->master_id)
return 0;
+ // ŒÄ‚Ñ–ß‚µ
+ if(mmd->recall_flag == 1){
+ if (mmd->recallcount < (mmd->recallmob_count+2) ){
+ mob_warp(md,-1,mmd->bl.x,mmd->bl.y,3);
+ mmd->recallcount += 1;
+ } else{
+ mmd->recall_flag = 0;
+ mmd->recallcount=0;
+ }
+ md->state.master_check = 1;
+ return 0;
+ }
// Since it is in the map on which the master is not, teleport is carried out and it pursues.
if( mmd->bl.m != md->bl.m ){
mob_warp(md,mmd->bl.m,mmd->bl.x,mmd->bl.y,3);
@@ -1380,7 +1426,7 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick)
}
// Although there is the master, since it is somewhat far, it approaches.
- if((!md->target_id || md->state.targettype == NONE_ATTACKABLE) && mob_can_move(md) &&
+ if((!md->target_id || md->state.targettype == NONE_ATTACKABLE) && mob_can_move(md) &&
(md->walkpath.path_pos>=md->walkpath.path_len || md->walkpath.path_len==0) && md->master_dist<15){
int i=0,dx,dy,ret;
if(md->master_dist>4) {
@@ -1426,7 +1472,7 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick)
struct map_session_data *sd=map_id2sd(mmd->target_id);
if(sd!=NULL && !pc_isdead(sd) && sd->invincible_timer == -1 && !pc_isinvisible(sd)){
- race=mob_db[md->class].race;
+ race=mob_db[md->class_].race;
if(mode&0x20 ||
(sd->sc_data[SC_TRICKDEAD].timer == -1 && sd->sc_data[SC_BASILICA].timer == -1 &&
( (!pc_ishiding(sd) && !sd->state.gangsterparadise) || ((race == 4 || race == 6) && !sd->perfect_hiding) ) ) ){ // –WŠQ‚ª‚È‚¢‚©”»’è
@@ -1444,7 +1490,7 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick)
struct map_session_data *sd=map_id2sd(md->target_id);
if(sd!=NULL && !pc_isdead(sd) && sd->invincible_timer == -1 && !pc_isinvisible(sd)){
- race=mob_db[mmd->class].race;
+ race=mob_db[mmd->class_].race;
if(mode&0x20 ||
(sd->sc_data[SC_TRICKDEAD].timer == -1 &&
(!(sd->status.option&0x06) || race==4 || race==6)
@@ -1485,23 +1531,34 @@ static int mob_randomwalk(struct mob_data *md,int tick)
nullpo_retr(0, md);
- speed=battle_get_speed(&md->bl);
+ speed=status_get_speed(&md->bl);
if(DIFF_TICK(md->next_walktime,tick)<0){
int i,x,y,c,d=12-md->move_fail_count;
+ int mask[8][2] = {{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1}};
if(d<5) d=5;
for(i=0;i<retrycount;i++){ // Search of a movable place
int r=rand();
- x=md->bl.x+r%(d*2+1)-d;
- y=md->bl.y+r/(d*2+1)%(d*2+1)-d;
- if((c=map_getcell(md->bl.m,x,y))!=1 && c!=5 && mob_walktoxy(md,x,y,1)==0){
+ x=r%(d*2+1)-d;
+ y=r/(d*2+1)%(d*2+1)-d;
+ if (md->target_dir){
+ if (x<0) x=0-x;
+ if (y<0) y=0-y;
+ x *= mask[md->target_dir-1][0];
+ y *= mask[md->target_dir-1][1];
+ }
+ x+=md->bl.x;
+ y+=md->bl.y;
+
+ if((map_getcell(md->bl.m,x,y,CELL_CHKPASS)) && mob_walktoxy(md,x,y,1)==0){
md->move_fail_count=0;
break;
}
if(i+1>=retrycount){
md->move_fail_count++;
+ md->target_dir = 0;
if(md->move_fail_count>1000){
if(battle_config.error_log)
- printf("MOB cant move. random spawn %d, class = %d\n",md->bl.id,md->class);
+ printf("MOB cant move. random spawn %d, class = %d\n",md->bl.id,md->class_);
md->move_fail_count=0;
mob_spawn(md->bl.id);
}
@@ -1534,6 +1591,8 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
int i,dx,dy,ret,dist;
int attack_type=0;
int mode,race;
+ int search_size = AREA_SIZE*2;
+ int blind_flag = 0;
nullpo_retr(0, bl);
nullpo_retr(0, ap);
@@ -1541,7 +1600,6 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
tick=va_arg(ap,unsigned int);
-
if(DIFF_TICK(tick,md->last_thinktime)<MIN_MOBTHINKTIME)
return 0;
md->last_thinktime=tick;
@@ -1553,16 +1611,19 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
}
if(!md->mode)
- mode=mob_db[md->class].mode;
+ mode=mob_db[md->class_].mode;
else
mode=md->mode;
- race=mob_db[md->class].race;
+ race=mob_db[md->class_].race;
// Abnormalities
if((md->opt1 > 0 && md->opt1 != 6) || md->state.state==MS_DELAY || md->sc_data[SC_BLADESTOP].timer != -1)
return 0;
+ if (md->sc_data && md->sc_data[SC_BLIND].timer != -1)
+ blind_flag = 1;
+
if(!(mode&0x80) && md->target_id > 0)
md->target_id = 0;
@@ -1587,7 +1648,8 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
if(abl->type==BL_PC)
asd=(struct map_session_data *)abl;
if(asd==NULL || md->bl.m != abl->m || abl->prev == NULL || asd->invincible_timer != -1 || pc_isinvisible(asd) ||
- (dist=distance(md->bl.x,md->bl.y,abl->x,abl->y))>=32 || battle_check_target(bl,abl,BCT_ENEMY)==0)
+ (dist=distance(md->bl.x,md->bl.y,abl->x,abl->y))>=32 || battle_check_target(bl,abl,BCT_ENEMY)==0 ||
+ (blind_flag && dist>3))
md->attacked_id=0;
else {
//‹——£‚ª‰“‚¢ê‡‚̓^ƒQ‚ð•ÏX‚µ‚È‚¢
@@ -1614,15 +1676,16 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
if( (!md->target_id || md->state.targettype == NONE_ATTACKABLE) && mode&0x04 && !md->state.master_check &&
battle_config.monster_active_enable){
i=0;
+ search_size = (blind_flag) ? 3 : AREA_SIZE*2;
if(md->state.special_mob_ai){
map_foreachinarea(mob_ai_sub_hard_activesearch,md->bl.m,
- md->bl.x-AREA_SIZE*2,md->bl.y-AREA_SIZE*2,
- md->bl.x+AREA_SIZE*2,md->bl.y+AREA_SIZE*2,
+ md->bl.x-search_size,md->bl.y-search_size,
+ md->bl.x+search_size,md->bl.y+search_size,
0,md,&i);
}else{
map_foreachinarea(mob_ai_sub_hard_activesearch,md->bl.m,
- md->bl.x-AREA_SIZE*2,md->bl.y-AREA_SIZE*2,
- md->bl.x+AREA_SIZE*2,md->bl.y+AREA_SIZE*2,
+ md->bl.x-search_size,md->bl.y-search_size,
+ md->bl.x+search_size,md->bl.y+search_size,
BL_PC,md,&i);
}
}
@@ -1630,9 +1693,10 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
// The item search of a route monster
if( !md->target_id && mode&0x02 && !md->state.master_check){
i=0;
+ search_size = (blind_flag) ? 3 : AREA_SIZE*2;
map_foreachinarea(mob_ai_sub_hard_lootsearch,md->bl.m,
- md->bl.x-AREA_SIZE*2,md->bl.y-AREA_SIZE*2,
- md->bl.x+AREA_SIZE*2,md->bl.y+AREA_SIZE*2,
+ md->bl.x-search_size,md->bl.y-search_size,
+ md->bl.x+search_size,md->bl.y+search_size,
BL_ITEM,md,&i);
}
@@ -1644,13 +1708,13 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
else if(tbl->type==BL_MOB)
tmd=(struct mob_data *)tbl;
if(tsd || tmd) {
- if(tbl->m != md->bl.m || tbl->prev == NULL || (dist=distance(md->bl.x,md->bl.y,tbl->x,tbl->y))>=md->min_chase)
+ if(tbl->m != md->bl.m || tbl->prev == NULL || (dist=distance(md->bl.x,md->bl.y,tbl->x,tbl->y)) >= search_size || (blind_flag && dist>3))
mob_unlocktarget(md,tick); // •ʃ}ƒbƒv‚©AŽ‹ŠEŠO
else if( tsd && !(mode&0x20) && (tsd->sc_data[SC_TRICKDEAD].timer != -1 || tsd->sc_data[SC_BASILICA].timer != -1 ||
((pc_ishiding(tsd) || tsd->state.gangsterparadise) &&
!((race == 4 || race == 6) && !tsd->perfect_hiding) )) )
mob_unlocktarget(md,tick); // ƒXƒLƒ‹‚Ȃǂɂæ‚éô“G–WŠQ
- else if(!battle_check_range(&md->bl,tbl,mob_db[md->class].range)){
+ else if(!battle_check_range(&md->bl,tbl,mob_db[md->class_].range)){
// UŒ‚”͈͊O‚Ȃ̂ňړ®
if(!(mode&1)){ // ˆÚ“®‚µ‚È‚¢ƒ‚[ƒh
mob_unlocktarget(md,tick);
@@ -1663,9 +1727,11 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
// if(md->timer != -1 && (DIFF_TICK(md->next_walktime,tick)<0 || distance(md->to_x,md->to_y,tsd->bl.x,tsd->bl.y)<2) )
if(md->timer != -1 && md->state.state!=MS_ATTACK && (DIFF_TICK(md->next_walktime,tick)<0 || distance(md->to_x,md->to_y,tbl->x,tbl->y)<2) )
return 0; // Šù‚Ɉړ®’†
- if( !mob_can_reach(md,tbl,(md->min_chase>13)?md->min_chase:13) )
+ search_size = (blind_flag) ? 3 :
+ ((md->min_chase > 13) ? md->min_chase : 13);
+ if(!mob_can_reach(md,tbl, search_size))
mob_unlocktarget(md,tick); // ˆÚ“®‚Å‚«‚È‚¢‚̂Ń^ƒQ‰ðœiIW‚Æ‚©Hj
- else{
+ else {
// ’ÇÕ
md->next_walktime=tick+500;
i=0;
@@ -1692,15 +1758,15 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
ret=mob_walktoxy(md,md->bl.x+dx,md->bl.y+dy,0);
i++;
} while(ret && i<5);
-
+
if(ret){ // ˆÚ“®•s‰Â”\‚ÈŠ‚©‚ç‚ÌUŒ‚‚È‚ç2•à‰º‚é
if(dx<0) dx=2;
else if(dx>0) dx=-2;
if(dy<0) dy=2;
else if(dy>0) dy=-2;
mob_walktoxy(md,md->bl.x+dx,md->bl.y+dy,0);
+ }
}
- }
} else { // UŒ‚ŽË’ö”͈͓à
md->state.skillstate=MSS_ATTACK;
if(md->state.state==MS_WALK)
@@ -1708,23 +1774,17 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
if(md->state.state==MS_ATTACK)
return 0; // Šù‚ÉUŒ‚’†
mob_changestate(md,MS_ATTACK,attack_type);
-
-/* if(mode&0x08){ // ƒŠƒ“ƒNƒ‚ƒ“ƒXƒ^[
- map_foreachinarea(mob_ai_sub_hard_linksearch,md->bl.m,
- md->bl.x-13,md->bl.y-13,
- md->bl.x+13,md->bl.y+13,
- BL_MOB,md,&tsd->bl);
- }*/
}
return 0;
- }else{ // ƒ‹[ƒgƒ‚ƒ“ƒXƒ^[ˆ—
+ } else { // ƒ‹[ƒgƒ‚ƒ“ƒXƒ^[ˆ—
if(tbl == NULL || tbl->type != BL_ITEM ||tbl->m != md->bl.m ||
- (dist=distance(md->bl.x,md->bl.y,tbl->x,tbl->y))>=md->min_chase || !md->lootitem){
+ (dist=distance(md->bl.x,md->bl.y,tbl->x,tbl->y))>=md->min_chase || !md->lootitem |
+ (blind_flag && dist>=4)){
// ‰“‚·‚¬‚é‚©ƒAƒCƒeƒ€‚ª‚È‚­‚È‚Á‚½
mob_unlocktarget(md,tick);
if(md->state.state==MS_WALK)
mob_stop_walking(md,1); // •às’†‚È‚ç’âŽ~
- }else if(dist){
+ } else if(dist) {
if(!(mode&1)){ // ˆÚ“®‚µ‚È‚¢ƒ‚[ƒh
mob_unlocktarget(md,tick);
return 0;
@@ -1838,7 +1898,8 @@ static int mob_ai_hard(int tid,unsigned int tick,int id,int data)
*/
static int mob_ai_sub_lazy(void * key,void * data,va_list app)
{
- struct mob_data *md=data;
+ struct mob_data *md=(struct mob_data *)data;
+ struct mob_data *mmd=NULL;
unsigned int tick;
va_list ap;
@@ -1849,8 +1910,9 @@ static int mob_ai_sub_lazy(void * key,void * data,va_list app)
if(md->bl.type!=BL_MOB)
return 0;
- if(!md->bl.type || md->bl.type!=BL_MOB)
- return 0;
+ if (md->master_id > 0) {
+ mmd = (struct mob_data *)map_id2bl(md->master_id); //Ž©•ª‚ÌBOSS‚Ìî•ñ
+ }
tick=va_arg(ap,unsigned int);
@@ -1864,8 +1926,14 @@ static int mob_ai_sub_lazy(void * key,void * data,va_list app)
return 0;
}
+ // Žæ‚芪‚«ƒ‚ƒ“ƒXƒ^[‚̈—iŒÄ‚Ñ–ß‚µ‚³‚ê‚½Žžj
+ if(mmd && md->state.special_mob_ai == 0 && mmd->recall_flag == 1) {
+ mob_ai_sub_hard_slavemob (md,tick);
+ return 0;
+ }
+
if(DIFF_TICK(md->next_walktime,tick)<0 &&
- (mob_db[md->class].mode&1) && mob_can_move(md) ){
+ (mob_db[md->class_].mode&1) && mob_can_move(md) ){
if( map[md->bl.m].users>0 ){
// Since PC is in the same map, somewhat better negligent processing is carried out.
@@ -1876,7 +1944,7 @@ static int mob_ai_sub_lazy(void * key,void * data,va_list app)
// MOB which is not not the summons MOB but BOSS, either sometimes reboils.
else if( rand()%1000<MOB_LAZYWARPPERC && md->x0<=0 && md->master_id!=0 &&
- mob_db[md->class].mexp <= 0 && !(mob_db[md->class].mode & 0x20))
+ mob_db[md->class_].mexp <= 0 && !(mob_db[md->class_].mode & 0x20))
mob_spawn(md->bl.id);
}else{
@@ -1884,7 +1952,7 @@ static int mob_ai_sub_lazy(void * key,void * data,va_list app)
// MOB which is not BOSS which is not Summons MOB, either -- a case -- sometimes -- leaping
if( rand()%1000<MOB_LAZYWARPPERC && md->x0<=0 && md->master_id!=0 &&
- mob_db[md->class].mexp <= 0 && !(mob_db[md->class].mode & 0x20))
+ mob_db[md->class_].mexp <= 0 && !(mob_db[md->class_].mode & 0x20))
mob_warp(md,-1,-1,-1,-1);
}
@@ -1931,7 +1999,7 @@ static int mob_delay_item_drop(int tid,unsigned int tick,int id,int data)
{
struct delay_item_drop *ditem;
struct item temp_item;
- int flag;
+ int flag, drop_flag = 1;
nullpo_retr(0, ditem=(struct delay_item_drop *)id);
@@ -1940,18 +2008,45 @@ static int mob_delay_item_drop(int tid,unsigned int tick,int id,int data)
temp_item.amount = ditem->amount;
temp_item.identify = !itemdb_isequip3(temp_item.nameid);
- if(battle_config.item_auto_get){
- if(ditem->first_sd && (flag = pc_additem(ditem->first_sd,&temp_item,ditem->amount))){
- clif_additem(ditem->first_sd,0,0,flag);
- map_addflooritem(&temp_item,1,ditem->m,ditem->x,ditem->y,ditem->first_sd,ditem->second_sd,ditem->third_sd,0);
+ if (ditem->first_sd){
+ #if 0
+ if (ditem->first_sd->status.party_id > 0){
+ struct party *p;
+ if((p=party_search(ditem->first_sd->status.party_id)) && p->item){
+ struct map_session_data *sd = NULL;
+ int i;
+ for (i = p->itemc + 1; i!=p->itemc; i++) { // initialise counter and loop through the party
+ if (i >= MAX_PARTY)
+ i = 0; // reset counter to 1st person in party so it'll stop when it reaches "itemc"
+ if ((sd=p->member[i].sd)!=NULL && sd->bl.m == ditem->first_sd->bl.m)
+ break;
+ }
+ if (sd){ // if an appropiate party member was found
+ drop_flag = 0;
+ if ((p->itemc++) >= MAX_PARTY)
+ p->itemc = 0;
+ if ((flag = pc_additem(ditem->first_sd,&temp_item,ditem->amount))) {
+ clif_additem(ditem->first_sd,0,0,flag);
+ drop_flag = 1;
+ }
+ }
+ }
+ } else
+ #endif
+ if(battle_config.item_auto_get || ditem->first_sd->autoloot){//Autoloot added by Upa-Kun
+ drop_flag = 0;
+ if((flag = pc_additem(ditem->first_sd,&temp_item,ditem->amount))){
+ clif_additem(ditem->first_sd,0,0,flag);
+ drop_flag = 1;
+ }
}
- free(ditem);
- return 0;
}
- map_addflooritem(&temp_item,1,ditem->m,ditem->x,ditem->y,ditem->first_sd,ditem->second_sd,ditem->third_sd,0);
+ if (drop_flag) {
+ map_addflooritem(&temp_item,1,ditem->m,ditem->x,ditem->y,ditem->first_sd,ditem->second_sd,ditem->third_sd,0);
+ }
- free(ditem);
+ aFree(ditem);
return 0;
}
@@ -1962,22 +2057,49 @@ static int mob_delay_item_drop(int tid,unsigned int tick,int id,int data)
static int mob_delay_item_drop2(int tid,unsigned int tick,int id,int data)
{
struct delay_item_drop2 *ditem;
- int flag;
+ int flag, drop_flag = 1;
nullpo_retr(0, ditem=(struct delay_item_drop2 *)id);
- if(battle_config.item_auto_get){
- if(ditem->first_sd && (flag = pc_additem(ditem->first_sd,&ditem->item_data,ditem->item_data.amount))){
- clif_additem(ditem->first_sd,0,0,flag);
- map_addflooritem(&ditem->item_data,ditem->item_data.amount,ditem->m,ditem->x,ditem->y,ditem->first_sd,ditem->second_sd,ditem->third_sd,0);
+ if (ditem->first_sd){
+ #if 0
+ if (ditem->first_sd->status.party_id > 0){
+ struct party *p;
+ if((p=party_search(ditem->first_sd->status.party_id)) && p->item){
+ struct map_session_data *sd = NULL;
+ int i;
+ for (i = p->itemc + 1; i!=p->itemc; i++) { // initialise counter and loop through the party
+ if (i >= MAX_PARTY)
+ i = 0; // reset counter to 1st person in party so it'll stop when it reaches "itemc"
+ if ((sd=p->member[i].sd)!=NULL && sd->bl.m == ditem->first_sd->bl.m)
+ break;
+ }
+ if (sd){ // if an appropiate party member was found
+ drop_flag = 0;
+ if ((p->itemc++) >= MAX_PARTY)
+ p->itemc = 0;
+ if((flag = pc_additem(ditem->first_sd,&ditem->item_data,ditem->item_data.amount))){
+ clif_additem(ditem->first_sd,0,0,flag);
+ drop_flag = 1;
+ }
+ }
+ }
+ } else
+ #endif
+ if(battle_config.item_auto_get || ditem->first_sd->autoloot){//Autoloot added by Upa-Kun
+ drop_flag = 0;
+ if((flag = pc_additem(ditem->first_sd,&ditem->item_data,ditem->item_data.amount))){
+ clif_additem(ditem->first_sd,0,0,flag);
+ drop_flag = 1;
+ }
}
- free(ditem);
- return 0;
}
- map_addflooritem(&ditem->item_data,ditem->item_data.amount,ditem->m,ditem->x,ditem->y,ditem->first_sd,ditem->second_sd,ditem->third_sd,0);
+ if (drop_flag) {
+ map_addflooritem(&ditem->item_data,ditem->item_data.amount,ditem->m,ditem->x,ditem->y,ditem->first_sd,ditem->second_sd,ditem->third_sd,0);
+ }
- free(ditem);
+ aFree(ditem);
return 0;
}
@@ -1985,44 +2107,49 @@ static int mob_delay_item_drop2(int tid,unsigned int tick,int id,int data)
* mob data is erased.
*------------------------------------------
*/
-int mob_delete(struct mob_data *md)
+void mob_unload(struct mob_data *md)
+{
+ nullpo_retv(md);
+ mob_remove_map(md, 0);
+ map_deliddb(&md->bl);
+ aFree(md);
+ md = NULL;
+}
+int mob_remove_map(struct mob_data *md, int type)
{
nullpo_retr(1, md);
if(md->bl.prev == NULL)
return 1;
mob_changestate(md,MS_DEAD,0);
- clif_clearchar_area(&md->bl,1);
+ clif_clearchar_area(&md->bl,type);
map_delblock(&md->bl);
- if(mob_get_viewclass(md->class) <= 1000)
- clif_clearchar_delay(gettick()+3000,&md->bl,0);
- mob_deleteslave(md);
- mob_setdelayspawn(md->bl.id);
+ if (md->lootitem){
+ aFree(md->lootitem);
+ md->lootitem = NULL;
+ }
+
return 0;
}
-
-int mob_catch_delete(struct mob_data *md,int type)
+int mob_delete(struct mob_data *md)
{
nullpo_retr(1, md);
- if(md->bl.prev == NULL)
- return 1;
- mob_changestate(md,MS_DEAD,0);
- clif_clearchar_area(&md->bl,type);
- map_delblock(&md->bl);
+ mob_remove_map(md, 1);
+ if (mob_get_viewclass(md->class_) <= 1000)
+ clif_clearchar_delay(gettick()+3000,&md->bl,0);
+ mob_deleteslave(md);
mob_setdelayspawn(md->bl.id);
return 0;
}
-
int mob_timer_delete(int tid, unsigned int tick, int id, int data)
{
- struct block_list *bl=map_id2bl(id);
- struct mob_data *md;
-
- nullpo_retr(0, bl);
+ struct mob_data *md=(struct mob_data *)map_id2bl(id);
+ nullpo_retr(0, md);
- md = (struct mob_data *)bl;
- mob_catch_delete(md,3);
+//for Alchemist CANNIBALIZE [Lupus]
+ mob_remove_map(md, 3);
+ mob_setdelayspawn(md->bl.id);
return 0;
}
@@ -2074,15 +2201,17 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
int mvp_damage,max_hp;
unsigned int tick = gettick();
struct map_session_data *mvp_sd = NULL, *second_sd = NULL,*third_sd = NULL;
- double dmg_rate,tdmg,temp;
+ struct block_list *master = NULL;
+ double tdmg,temp;
struct item item;
int ret;
int drop_rate;
- int skill,sp;
-
+ int race;
+
nullpo_retr(0, md); //src‚ÍNULL‚ŌĂ΂ê‚éê‡‚à‚ ‚é‚Ì‚ÅA‘¼‚Ń`ƒFƒbƒN
- max_hp = battle_get_max_hp(&md->bl);
+ max_hp = status_get_max_hp(&md->bl);
+ race = status_get_race(&md->bl);
if(src && src->type == BL_PC) {
sd = (struct map_session_data *)src;
@@ -2108,7 +2237,7 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
return 0;
}
- if(md->sc_data[SC_ENDURE].timer == -1)
+ if(battle_config.monster_damage_delay && md->sc_data[SC_ENDURE].timer == -1)
mob_stop_walking(md,3);
if(damage > max_hp>>2)
skill_stop_dancing(&md->bl,0);
@@ -2123,7 +2252,8 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
if(!(type&2)) {
if(sd!=NULL){
for(i=0,minpos=0,mindmg=0x7fffffff;i<DAMAGELOG_SIZE;i++){
- if(md->dmglog[i].id==sd->bl.id)
+ //if(md->dmglog[i].id==sd->bl.id)
+ if(md->dmglog[i].id==sd->status.char_id)
break;
if(md->dmglog[i].id==0){
minpos=i;
@@ -2137,7 +2267,8 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
if(i<DAMAGELOG_SIZE)
md->dmglog[i].dmg+=damage;
else {
- md->dmglog[minpos].id=sd->bl.id;
+ //md->dmglog[minpos].id=sd->bl.id;
+ md->dmglog[minpos].id=sd->status.char_id;
md->dmglog[minpos].dmg=damage;
}
@@ -2148,7 +2279,8 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
struct pet_data *pd = (struct pet_data *)src;
nullpo_retr(0, pd);
for(i=0,minpos=0,mindmg=0x7fffffff;i<DAMAGELOG_SIZE;i++){
- if(md->dmglog[i].id==pd->msd->bl.id)
+ //if(md->dmglog[i].id==pd->msd->bl.id)
+ if(md->dmglog[i].id==pd->msd->status.char_id)
break;
if(md->dmglog[i].id==0){
minpos=i;
@@ -2162,7 +2294,8 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
if(i<DAMAGELOG_SIZE)
md->dmglog[i].dmg+=(damage*battle_config.pet_attack_exp_rate)/100;
else {
- md->dmglog[minpos].id=pd->msd->bl.id;
+ //md->dmglog[minpos].id=pd->msd->bl.id;
+ md->dmglog[minpos].id=pd->msd->status.char_id;
md->dmglog[minpos].dmg=(damage*battle_config.pet_attack_exp_rate)/100;
}
}
@@ -2195,88 +2328,92 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
}
md->hp-=damage;
-
- if(md->class >= 1285 && md->class <=1287) { // guardian hp update [Valaris]
+
+ if(md->class_ >= 1285 && md->class_ <=1287) { // guardian hp update [Valaris]
struct guild_castle *gc=guild_mapname2gc(map[md->bl.m].name);
if(gc) {
- if(md->bl.id==gc->GID0) {
+ if(md->bl.id==gc->GID0) {
gc->Ghp0=md->hp;
if(gc->Ghp0<=0) {
guild_castledatasave(gc->castle_id,10,0);
guild_castledatasave(gc->castle_id,18,0);
}
- }
- if(md->bl.id==gc->GID1) {
+ }
+ if(md->bl.id==gc->GID1) {
gc->Ghp1=md->hp;
if(gc->Ghp1<=0) {
guild_castledatasave(gc->castle_id,11,0);
guild_castledatasave(gc->castle_id,19,0);
}
}
- if(md->bl.id==gc->GID2) {
+ if(md->bl.id==gc->GID2) {
gc->Ghp2=md->hp;
if(gc->Ghp2<=0) {
guild_castledatasave(gc->castle_id,12,0);
guild_castledatasave(gc->castle_id,20,0);
}
}
- if(md->bl.id==gc->GID3) {
+ if(md->bl.id==gc->GID3) {
gc->Ghp3=md->hp;
if(gc->Ghp3<=0) {
guild_castledatasave(gc->castle_id,13,0);
guild_castledatasave(gc->castle_id,21,0);
}
}
- if(md->bl.id==gc->GID4) {
+ if(md->bl.id==gc->GID4) {
gc->Ghp4=md->hp;
if(gc->Ghp4<=0) {
guild_castledatasave(gc->castle_id,14,0);
guild_castledatasave(gc->castle_id,22,0);
}
}
- if(md->bl.id==gc->GID5) {
+ if(md->bl.id==gc->GID5) {
gc->Ghp5=md->hp;
if(gc->Ghp5<=0) {
guild_castledatasave(gc->castle_id,15,0);
guild_castledatasave(gc->castle_id,23,0);
}
}
- if(md->bl.id==gc->GID6) {
+ if(md->bl.id==gc->GID6) {
gc->Ghp6=md->hp;
if(gc->Ghp6<=0) {
guild_castledatasave(gc->castle_id,16,0);
guild_castledatasave(gc->castle_id,24,0);
}
}
- if(md->bl.id==gc->GID7) {
+ if(md->bl.id==gc->GID7) {
gc->Ghp7=md->hp;
if(gc->Ghp7<=0) {
guild_castledatasave(gc->castle_id,17,0);
guild_castledatasave(gc->castle_id,25,0);
-
+
}
}
}
} // end addition [Valaris]
-
+
if(md->option&2 )
- skill_status_change_end(&md->bl, SC_HIDING, -1);
+ status_change_end(&md->bl, SC_HIDING, -1);
if(md->option&4 )
- skill_status_change_end(&md->bl, SC_CLOAKING, -1);
+ status_change_end(&md->bl, SC_CLOAKING, -1);
if(md->state.special_mob_ai == 2){//ƒXƒtƒBƒA[ƒ}ƒCƒ“
int skillidx=0;
-
- if((skillidx=mob_skillid2skillidx(md->class,NPC_SELFDESTRUCTION2))>=0){
+
+ if((skillidx=mob_skillid2skillidx(md->class_,NPC_SELFDESTRUCTION2))>=0){
md->mode |= 0x1;
md->next_walktime=tick;
mobskill_use_id(md,&md->bl,skillidx);//Ž©”š‰r¥ŠJŽn
md->state.special_mob_ai++;
}
+ if (src && md->master_id==src->id)
+ md->target_dir=map_calc_dir(src,md->bl.x,md->bl.y)+1;
}
if(md->hp>0){
+ if (battle_config.show_mob_hp)
+ clif_update_mobhp (md);
return 0;
}
@@ -2289,19 +2426,33 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
memset(tmpsd,0,sizeof(tmpsd));
memset(pt,0,sizeof(pt));
- max_hp = battle_get_max_hp(&md->bl);
+ max_hp = status_get_max_hp(&md->bl);
if(src && src->type == BL_MOB)
mob_unlocktarget((struct mob_data *)src,tick);
- /* ƒ\ƒEƒ‹ƒhƒŒƒCƒ“ */
- if(sd && (skill=pc_checkskill(sd,HW_SOULDRAIN))>0){
- clif_skill_nodamage(src,&md->bl,HW_SOULDRAIN,skill,1);
- sp = (battle_get_lv(&md->bl))*(65+15*skill)/100;
- if(sd->status.sp + sp > sd->status.max_sp)
- sp = sd->status.max_sp - sd->status.sp;
- sd->status.sp += sp;
- clif_heal(sd->fd,SP_SP,sp);
+
+ if(sd) {
+ int sp = 0, hp = 0;
+ if (sd->state.attack_type == BF_MAGIC && (i=pc_checkskill(sd,HW_SOULDRAIN))>0){ /* ƒ\ƒEƒ‹ƒhƒŒƒCƒ“ */
+ clif_skill_nodamage(src,&md->bl,HW_SOULDRAIN,i,1);
+ sp += (status_get_lv(&md->bl))*(65+15*i)/100;
+ }
+ sp += sd->sp_gain_value;
+ sp += sd->sp_gain_race[race];
+ hp += sd->hp_gain_value;
+ if (sp > 0) {
+ if(sd->status.sp + sp > sd->status.max_sp)
+ sp = sd->status.max_sp - sd->status.sp;
+ sd->status.sp += sp;
+ clif_heal(sd->fd,SP_SP,sp);
+ }
+ if (hp > 0) {
+ if(sd->status.hp + hp > sd->status.max_hp)
+ hp = sd->status.max_hp - sd->status.hp;
+ sd->status.hp += hp;
+ clif_heal(sd->fd,SP_HP,hp);
+ }
}
// mapŠO‚ÉÁ‚¦‚½l‚ÍŒvŽZ‚©‚眂­‚Ì‚Å
@@ -2311,7 +2462,12 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
for(i=0,count=0,mvp_damage=0;i<DAMAGELOG_SIZE;i++){
if(md->dmglog[i].id==0)
continue;
- tmpsd[i] = map_id2sd(md->dmglog[i].id);
+ // Will this slow things down too much?
+ tmpsd[i] = map_charid2sd(md->dmglog[i].id);
+ // try finding again
+ if(tmpsd[i] == NULL)
+ tmpsd[i] = map_id2sd(md->dmglog[i].id);
+ // if we still can't find the player
if(tmpsd[i] == NULL)
continue;
count++;
@@ -2327,64 +2483,81 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
}
}
- // [MouseJstr]
- if((map[md->bl.m].flag.pvp == 0) || (battle_config.pvp_exp == 1)) {
-
- if((double)max_hp < tdmg)
- dmg_rate = ((double)max_hp) / tdmg;
- else dmg_rate = 1;
+ // [MouseJstr]
+ if((map[md->bl.m].flag.pvp == 0) || (battle_config.pvp_exp == 1)) {
// ŒoŒ±’l‚Ì•ª”z
for(i=0;i<DAMAGELOG_SIZE;i++){
int pid,base_exp,job_exp,flag=1,zeny=0;
double per;
struct party *p;
- if(tmpsd[i]==NULL || tmpsd[i]->bl.m != md->bl.m)
+ if(tmpsd[i]==NULL || tmpsd[i]->bl.m != md->bl.m || pc_isdead(tmpsd[i]))
continue;
-/* jAthena's exp formula
- per = ((double)md->dmglog[i].dmg)*(9.+(double)((count > 6)? 6:count))/10./((double)max_hp) * dmg_rate;
- temp = ((double)mob_db[md->class].base_exp * (double)battle_config.base_exp_rate / 100. * per);
- base_exp = (temp > 2147483647.)? 0x7fffffff:(int)temp;
- if(mob_db[md->class].base_exp > 0 && base_exp < 1) base_exp = 1;
- if(base_exp < 0) base_exp = 0;
- temp = ((double)mob_db[md->class].job_exp * (double)battle_config.job_exp_rate / 100. * per);
- job_exp = (temp > 2147483647.)? 0x7fffffff:(int)temp;
- if(mob_db[md->class].job_exp > 0 && job_exp < 1) job_exp = 1;
- if(job_exp < 0) job_exp = 0;
-*/
-//eAthena's exp formula rather than jAthena's
- per=(double)md->dmglog[i].dmg*256*(9+(double)((count > 6)? 6:count))/10/(double)max_hp;
- if(per>512) per=512;
- if(per<1) per=1;
- base_exp=mob_db[md->class].base_exp*per/256;
-
- if(base_exp < 1) base_exp = 1;
- if(sd && md && battle_config.pk_mode==1 && (mob_db[md->class].lv - sd->status.base_level >= 20)) {
- base_exp*=1.15; // pk_mode additional exp if monster >20 levels [Valaris]
- }
- job_exp=mob_db[md->class].job_exp*per/256;
- if(job_exp < 1) job_exp = 1;
- if(sd && md && battle_config.pk_mode==1 && (mob_db[md->class].lv - sd->status.base_level >= 20)) {
- job_exp*=1.15; // pk_mode additional exp if monster >20 levels [Valaris]
+
+ if (battle_config.exp_calc_type == 0) {
+ // jAthena's exp formula
+ per = ((double)md->dmglog[i].dmg)*(9.+(double)((count > 6)? 6:count))/10./tdmg;
+ temp = (double)mob_db[md->class_].base_exp * per;
+ base_exp = (temp > 2147483647.)? 0x7fffffff:(int)temp;
+ if(mob_db[md->class_].base_exp > 0 && base_exp < 1) base_exp = 1;
+ if(base_exp < 0) base_exp = 0;
+ temp = (double)mob_db[md->class_].job_exp * per;
+ job_exp = (temp > 2147483647.)? 0x7fffffff:(int)temp;
+ if(mob_db[md->class_].job_exp > 0 && job_exp < 1) job_exp = 1;
+ if(job_exp < 0) job_exp = 0;
}
- if(md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1) { // for summoned creatures [Valaris]
- base_exp = 0;
- job_exp = 0;
+ else if (battle_config.exp_calc_type == 1) {
+ //eAthena's exp formula rather than jAthena's
+ per=(double)md->dmglog[i].dmg*256*(9+(double)((count > 6)? 6:count))/10/(double)max_hp;
+ if(per>512) per=512;
+ if(per<1) per=1;
+ base_exp=(int) (mob_db[md->class_].base_exp*per/256);
+ if(base_exp < 1) base_exp = 1;
+ job_exp=(int) (mob_db[md->class_].job_exp*per/256);
+ if(job_exp < 1) job_exp = 1;
}
else {
- if(battle_config.zeny_from_mobs) {
- if(md->level > 0) zeny=(md->level+rand()%md->level)*per/256; // zeny calculation moblv + random moblv [Valaris]
- if(mob_db[md->class].mexp > 0)
+ //eAthena's exp formula rather than jAthena's, but based on total damage dealt
+ per=(double)md->dmglog[i].dmg*256*(9+(double)((count > 6)? 6:count))/10/tdmg;
+ if(per>512) per=512;
+ if(per<1) per=1;
+ base_exp=(int) (mob_db[md->class_].base_exp*per/256);
+ if(base_exp < 1) base_exp = 1;
+ job_exp=(int) (mob_db[md->class_].job_exp*per/256);
+ if(job_exp < 1) job_exp = 1;
+ }
+
+ if(sd) {
+ int rate;
+ if ((rate = sd->expaddrace[race]) > 0) {
+ base_exp = (100+rate)*base_exp/100;
+ job_exp = (100+rate)*job_exp/100;
+ }
+ if (battle_config.pk_mode && (mob_db[md->class_].lv - sd->status.base_level >= 20)) {
+ base_exp = (int) (base_exp *1.15); // pk_mode additional exp if monster >20 levels [Valaris]
+ job_exp = (int) (job_exp * 1.15);
+ }
+ }
+ if(md->master_id) {
+ if(((master = map_id2bl(md->master_id)) && status_get_mode(master)&0x20) || // check if its master is a boss (MVP's and minibosses)
+ (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1)) { // for summoned creatures [Valaris]
+ base_exp = 0;
+ job_exp = 0;
+ }
+ } else {
+ if(battle_config.zeny_from_mobs) {
+ if(md->level > 0) zeny=(int) ((md->level+rand()%md->level)*per/256); // zeny calculation moblv + random moblv [Valaris]
+ if(mob_db[md->class_].mexp > 0)
zeny*=rand()%250;
}
- if(battle_config.mobs_level_up && md->level > mob_db[md->class].lv) { // [Valaris]
- job_exp+=((md->level-mob_db[md->class].lv)*mob_db[md->class].job_exp*.03)*per/256;
- base_exp+=((md->level-mob_db[md->class].lv)*mob_db[md->class].base_exp*.03)*per/256;
+ if(battle_config.mobs_level_up && md->level > mob_db[md->class_].lv) { // [Valaris]
+ job_exp+=(int) (((md->level-mob_db[md->class_].lv)*mob_db[md->class_].job_exp*.03)*per/256);
+ base_exp+=(int) (((md->level-mob_db[md->class_].lv)*mob_db[md->class_].base_exp*.03)*per/256);
}
}
-
+
if((pid=tmpsd[i]->status.party_id)>0){ // ƒp[ƒeƒB‚É“ü‚Á‚Ä‚¢‚é
- int j=0;
+ int j;
for(j=0;j<pnum;j++) // Œö•½ƒp[ƒeƒBƒŠƒXƒg‚É‚¢‚é‚©‚Ç‚¤‚©
if(pt[j].id==pid)
break;
@@ -2422,26 +2595,31 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
// item drop
if(!(type&1)) {
- int log_item[8] = {0};
- for(i=0;i<8;i++){
+ int log_item[10] = {0}; //8 -> 10 Lupus
+ int drop_ore = -1,drop_items=0; //slot N for DROP LOG, number of dropped items
+ for(i=0;i<10;i++){ // 8 -> 10 Lupus
struct delay_item_drop *ditem;
int drop_rate;
- if(md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1) // Added [Valaris]
+ if((master && status_get_mode(master)&0x20) || // check if its master is a boss (MVP's and minibosses)
+ (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1)) // Added [Valaris]
break; // End
- if(mob_db[md->class].dropitem[i].nameid <= 0)
+ if(mob_db[md->class_].dropitem[i].nameid <= 0)
continue;
- drop_rate = mob_db[md->class].dropitem[i].p;
- if(drop_rate <= 0 && battle_config.drop_rate0item)
+ drop_rate = mob_db[md->class_].dropitem[i].p;
+ if(drop_rate <= 0 && !battle_config.drop_rate0item)
drop_rate = 1;
if(battle_config.drops_by_luk>0 && sd && md) drop_rate+=(sd->status.luk*battle_config.drops_by_luk)/100; // drops affected by luk [Valaris]
- if(sd && md && battle_config.pk_mode==1 && (mob_db[md->class].lv - sd->status.base_level >= 20)) drop_rate*=1.25; // pk_mode increase drops if 20 level difference [Valaris]
- if(drop_rate <= rand()%10000)
+ if(sd && md && battle_config.pk_mode==1 && (mob_db[md->class_].lv - sd->status.base_level >= 20)) drop_rate = (int) (drop_rate*1.25); // pk_mode increase drops if 20 level difference [Valaris]
+ if(drop_rate < rand() % 10000 + 1) { //fixed 0.01% impossible drops bug [Lupus]
+ drop_ore = i; //we remember an empty slot to put there ORE DISCOVERY drop later.
continue;
+ }
+ drop_items++; //we count if there were any drops
ditem=(struct delay_item_drop *)aCalloc(1,sizeof(struct delay_item_drop));
- ditem->nameid = mob_db[md->class].dropitem[i].nameid;
+ ditem->nameid = mob_db[md->class_].dropitem[i].nameid;
log_item[i] = ditem->nameid;
ditem->amount = 1;
ditem->m = md->bl.m;
@@ -2453,18 +2631,14 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
add_timer(tick+500+i,mob_delay_item_drop,(int)ditem,0);
}
- #ifndef TXT_ONLY
- if(log_config.drop > 0)
- log_drop(mvp_sd, md->class, log_item);
- #endif
-
// Ore Discovery [Celest]
- if (pc_checkskill(sd,BS_FINDINGORE)>0 && 1 >= rand()%1000) {
+ if (sd == mvp_sd && pc_checkskill(sd,BS_FINDINGORE)>0 && battle_config.finding_ore_rate/100 >= rand()%1000) {
struct delay_item_drop *ditem;
- int itemid[17] = { 714, 756, 757, 969, 984, 985, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1002 };
ditem=(struct delay_item_drop *)aCalloc(1,sizeof(struct delay_item_drop));
- ditem->nameid = itemid[rand()%17];
- log_item[i] = ditem->nameid;
+ ditem->nameid = itemdb_searchrandomid(6);
+ if (drop_ore<0) i=8; //we have only 10 slots in LOG, there's a check to not overflow (9th item usually a card, so we use 8th slot)
+ log_item[i] = ditem->nameid; //it's for logging only
+ drop_items++; //we count if there were any drops
ditem->amount = 1;
ditem->m = md->bl.m;
ditem->x = md->bl.x;
@@ -2475,20 +2649,18 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
add_timer(tick+500+i,mob_delay_item_drop,(int)ditem,0);
}
- #ifndef TXT_ONLY
- if(log_config.drop > 0)
- log_drop(mvp_sd, md->class, log_item);
- #endif
+ //this drop log contains ALL dropped items + ORE (if there was ORE Recovery) [Lupus]
+ if(sd && log_config.drop > 0 && drop_items) //we check were there any drops.. and if not - don't write the log
+ log_drop(sd, md->class_, log_item); //mvp_sd
if(sd && sd->state.attack_type == BF_WEAPON) {
for(i=0;i<sd->monster_drop_item_count;i++) {
struct delay_item_drop *ditem;
- int race = battle_get_race(&md->bl);
if(sd->monster_drop_itemid[i] <= 0)
continue;
- if(sd->monster_drop_race[i] & (1<<race) ||
- (mob_db[md->class].mode & 0x20 && sd->monster_drop_race[i] & 1<<10) ||
- (!(mob_db[md->class].mode & 0x20) && sd->monster_drop_race[i] & 1<<11) ) {
+ if(sd->monster_drop_race[i] & (1<<race) ||
+ (mob_db[md->class_].mode & 0x20 && sd->monster_drop_race[i] & 1<<10) ||
+ (!(mob_db[md->class_].mode & 0x20) && sd->monster_drop_race[i] & 1<<11) ) {
if(sd->monster_drop_itemrate[i] <= rand()%10000)
continue;
@@ -2505,7 +2677,7 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
}
}
if(sd->get_zeny_num > 0)
- pc_getzeny(sd,mob_db[md->class].lv*10 + rand()%(sd->get_zeny_num+1));
+ pc_getzeny(sd,mob_db[md->class_].lv*10 + rand()%(sd->get_zeny_num+1));
}
if(md->lootitem) {
for(i=0;i<md->lootitem_count;i++) {
@@ -2525,11 +2697,11 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
}
// mvpˆ—
- if(mvp_sd && mob_db[md->class].mexp > 0 ){
+ if(mvp_sd && mob_db[md->class_].mexp > 0 ){
int log_mvp[2] = {0};
int j;
int mexp;
- temp = ((double)mob_db[md->class].mexp * (double)battle_config.mvp_exp_rate * (9.+(double)count)/1000.);
+ temp = ((double)mob_db[md->class_].mexp * (9.+(double)count)/10.); //[Gengar]
mexp = (temp > 2147483647.)? 0x7fffffff:(int)temp;
if(mexp < 1) mexp = 1;
clif_mvp_effect(mvp_sd); // ƒGƒtƒFƒNƒg
@@ -2538,19 +2710,20 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
log_mvp[1] = mexp;
for(j=0;j<3;j++){
i = rand() % 3;
- if(mob_db[md->class].mvpitem[i].nameid <= 0)
+ if(mob_db[md->class_].mvpitem[i].nameid <= 0)
continue;
- drop_rate = mob_db[md->class].mvpitem[i].p;
- if(drop_rate <= 0 && battle_config.drop_rate0item)
+ drop_rate = mob_db[md->class_].mvpitem[i].p;
+ if(drop_rate <= 0 && !battle_config.drop_rate0item)
drop_rate = 1;
- if(drop_rate < battle_config.item_drop_mvp_min)
+/* if(drop_rate < battle_config.item_drop_mvp_min)
drop_rate = battle_config.item_drop_mvp_min;
- if(drop_rate > battle_config.item_drop_mvp_max)
+ else if(drop_rate > battle_config.item_drop_mvp_max) //fixed
drop_rate = battle_config.item_drop_mvp_max;
- if(drop_rate <= rand()%10000)
+*/
+ if(drop_rate <= rand()%10000+1) //if ==0, then it doesn't drop
continue;
memset(&item,0,sizeof(item));
- item.nameid=mob_db[md->class].mvpitem[i].nameid;
+ item.nameid=mob_db[md->class_].mvpitem[i].nameid;
item.identify=!itemdb_isequip3(item.nameid);
clif_mvp_item(mvp_sd,item.nameid);
log_mvp[0] = item.nameid;
@@ -2562,10 +2735,9 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
}
break;
}
- #ifndef TXT_ONLY
- if(log_config.mvpdrop > 0)
- log_mvpdrop(mvp_sd, md->class, log_mvp);
- #endif
+
+ if(log_config.mvpdrop > 0)
+ log_mvpdrop(mvp_sd, md->class_, log_mvp);
}
} // [MouseJstr]
@@ -2574,7 +2746,7 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
if(md->npc_event[0] && strcmp(((md->npc_event)+strlen(md->npc_event)-13),"::OnAgitBreak") == 0) {
printf("MOB.C: Run NPC_Event[OnAgitBreak].\n");
if (agit_flag == 1) //Call to Run NPC_Event[OnAgitBreak]
- guild_agit_break(md);
+ guild_agit_break(md);
}
// SCRIPTŽÀs
@@ -2590,7 +2762,7 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
struct map_session_data *tmpsd;
int i;
for(i=0;i<fd_max;i++){
- if(session[i] && (tmpsd=session[i]->session_data) && tmpsd->state.auth) {
+ if(session[i] && (tmpsd= (struct map_session_data *) session[i]->session_data) && tmpsd->state.auth) {
if(md->bl.m == tmpsd->bl.m) {
sd = tmpsd;
break;
@@ -2606,7 +2778,7 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
clif_clearchar_area(&md->bl,1);
if(md->level) md->level=0;
map_delblock(&md->bl);
- if(mob_get_viewclass(md->class) <= 1000)
+ if(mob_get_viewclass(md->class_) <= 1000)
clif_clearchar_delay(tick+3000,&md->bl,0);
mob_deleteslave(md);
mob_setdelayspawn(md->bl.id);
@@ -2622,26 +2794,26 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
int mob_class_change(struct mob_data *md,int *value)
{
unsigned int tick = gettick();
- int i,c,hp_rate,max_hp,class,count = 0;
+ int i,c,hp_rate,max_hp,class_,count = 0;
nullpo_retr(0, md);
nullpo_retr(0, value);
- if(value[0]<=1000 || value[0]>2000)
+ if(value[0]<=1000 || value[0]>MAX_MOB_DB)
return 0;
if(md->bl.prev == NULL) return 0;
- while(count < 5 && value[count] > 1000 && value[count] <= 2000) count++;
+ while(count < 5 && value[count] > 1000 && value[count] <= MAX_MOB_DB) count++;
if(count < 1) return 0;
- class = value[rand()%count];
- if(class<=1000 || class>2000) return 0;
+ class_ = value[rand()%count];
+ if(class_<=1000 || class_>MAX_MOB_DB) return 0;
- max_hp = battle_get_max_hp(&md->bl);
+ max_hp = status_get_max_hp(&md->bl);
hp_rate = md->hp*100/max_hp;
- clif_mob_class_change(md,class);
- md->class = class;
- max_hp = battle_get_max_hp(&md->bl);
+ clif_mob_class_change(md,class_);
+ md->class_ = class_;
+ max_hp = status_get_max_hp(&md->bl);
if(battle_config.monster_class_change_full_recover==1) {
md->hp = max_hp;
memset(md->dmglog,0,sizeof(md->dmglog));
@@ -2651,14 +2823,14 @@ int mob_class_change(struct mob_data *md,int *value)
if(md->hp > max_hp) md->hp = max_hp;
else if(md->hp < 1) md->hp = 1;
- memcpy(md->name,mob_db[class].jname,24);
+ memcpy(md->name,mob_db[class_].jname,24);
memset(&md->state,0,sizeof(md->state));
md->attacked_id = 0;
md->target_id = 0;
md->move_fail_count = 0;
- md->speed = mob_db[md->class].speed;
- md->def_ele = mob_db[md->class].element;
+ md->speed = mob_db[md->class_].speed;
+ md->def_ele = mob_db[md->class_].element;
mob_changestate(md,MS_IDLE,0);
skill_castcancel(&md->bl,0);
@@ -2667,14 +2839,13 @@ int mob_class_change(struct mob_data *md,int *value)
md->next_walktime = tick+rand()%50+5000;
md->attackabletime = tick;
md->canmove_tick = tick;
- md->sg_count=0;
for(i=0,c=tick-1000*3600*10;i<MAX_MOBSKILL;i++)
md->skilldelay[i] = c;
md->skillid=0;
md->skilllv=0;
- if(md->lootitem == NULL && mob_db[class].mode&0x02)
+ if(md->lootitem == NULL && mob_db[class_].mode&0x02)
md->lootitem=(struct item *)aCalloc(LOOTITEM_SIZE,sizeof(struct item));
skill_clear_unitgroup(&md->bl);
@@ -2692,15 +2863,16 @@ int mob_class_change(struct mob_data *md,int *value)
*/
int mob_heal(struct mob_data *md,int heal)
{
- int max_hp = battle_get_max_hp(&md->bl);
+ int max_hp;
nullpo_retr(0, md);
+ max_hp = status_get_max_hp(&md->bl);
md->hp += heal;
if( max_hp < md->hp )
md->hp = max_hp;
- if(md->class >= 1285 && md->class <=1287) { // guardian hp update [Valaris]
+ if(md->class_ >= 1285 && md->class_ <=1287) { // guardian hp update [Valaris]
struct guild_castle *gc=guild_mapname2gc(map[md->bl.m].name);
if(gc) {
if(md->bl.id==gc->GID0) gc->Ghp0=md->hp;
@@ -2714,6 +2886,9 @@ int mob_heal(struct mob_data *md,int heal)
}
} // end addition [Valaris]
+ if (battle_config.show_mob_hp)
+ clif_update_mobhp(md);
+
return 0;
}
@@ -2755,7 +2930,8 @@ int mob_warpslave(struct mob_data *md,int x, int y)
*/
int mob_warp(struct mob_data *md,int m,int x,int y,int type)
{
- int i=0,c,xs=0,ys=0,bx=x,by=y;
+ int i=0,xs=0,ys=0,bx=x,by=y;
+ int tick = gettick();
nullpo_retr(0, md);
@@ -2769,14 +2945,14 @@ int mob_warp(struct mob_data *md,int m,int x,int y,int type)
return 0;
clif_clearchar_area(&md->bl,type);
}
- skill_unit_out_all(&md->bl,gettick(),1);
+ skill_unit_move(&md->bl,tick,0);
map_delblock(&md->bl);
if(bx>0 && by>0){ // ˆÊ’uŽw’è‚ÌꇎüˆÍ‚XƒZƒ‹‚ð’Tõ
xs=ys=9;
}
- while( ( x<0 || y<0 || ((c=read_gat(m,x,y))==1 || c==5) ) && (i++)<1000 ){
+ while( ( x<0 || y<0 || map_getcell(m,x,y,CELL_CHKNOPASS)) && (i++)<1000 ){
if( xs>0 && ys>0 && i<250 ){ // Žw’èˆÊ’u•t‹ß‚Ì’Tõ
x=bx+rand()%xs-xs/2;
y=by+rand()%ys-ys/2;
@@ -2793,7 +2969,7 @@ int mob_warp(struct mob_data *md,int m,int x,int y,int type)
}else {
m=md->bl.m;
if(battle_config.error_log==1)
- printf("MOB %d warp failed, class = %d\n",md->bl.id,md->class);
+ printf("MOB %d warp failed, class = %d\n",md->bl.id,md->class_);
}
md->target_id=0; // ƒ^ƒQ‚ð‰ðœ‚·‚é
@@ -2804,10 +2980,11 @@ int mob_warp(struct mob_data *md,int m,int x,int y,int type)
if(type>0 && i==1000) {
if(battle_config.battle_log)
- printf("MOB %d warp to (%d,%d), class = %d\n",md->bl.id,x,y,md->class);
+ printf("MOB %d warp to (%d,%d), class = %d\n",md->bl.id,x,y,md->class_);
}
map_addblock(&md->bl);
+ skill_unit_move(&md->bl,tick,1);
if(type>0)
{
clif_spawnmob(md);
@@ -2833,7 +3010,6 @@ int mob_countslave_sub(struct block_list *bl,va_list ap)
nullpo_retr(0, c=va_arg(ap,int *));
nullpo_retr(0, md = (struct mob_data *)bl);
-
if( md->master_id==id )
(*c)++;
return 0;
@@ -2860,7 +3036,7 @@ int mob_countslave(struct mob_data *md)
int mob_summonslave(struct mob_data *md2,int *value,int amount,int flag)
{
struct mob_data *md;
- int bx,by,m,count = 0,class,k,a = amount;
+ int bx,by,m,count = 0,class_,k,a = amount;
nullpo_retr(0, md2);
nullpo_retr(0, value);
@@ -2869,24 +3045,24 @@ int mob_summonslave(struct mob_data *md2,int *value,int amount,int flag)
by=md2->bl.y;
m=md2->bl.m;
- if(value[0]<=1000 || value[0]>2000) // ’l‚ªˆÙí‚Ȃ碊«‚ðŽ~‚ß‚é
+ if(value[0]<=1000 || value[0]>MAX_MOB_DB) // ’l‚ªˆÙí‚Ȃ碊«‚ðŽ~‚ß‚é
return 0;
- while(count < 5 && value[count] > 1000 && value[count] <= 2000) count++;
+ while(count < 21 && value[count] > 1000 && value[count] <= 2000) count++;
if(count < 1) return 0;
for(k=0;k<count;k++) {
amount = a;
- class = value[k];
- if(class<=1000 || class>2000) continue;
+ class_ = value[k];
+ if(class_<=1000 || class_>MAX_MOB_DB) continue;
for(;amount>0;amount--){
- int x=0,y=0,c=0,i=0;
+ int x=0,y=0,i=0;
md=(struct mob_data *)aCalloc(1,sizeof(struct mob_data));
- if(mob_db[class].mode&0x02)
+ if(mob_db[class_].mode&0x02)
md->lootitem=(struct item *)aCalloc(LOOTITEM_SIZE,sizeof(struct item));
else
md->lootitem=NULL;
- while((x<=0 || y<=0 || (c=map_getcell(m,x,y))==1 || c==5 ) && (i++)<100){
+ while((x<=0 || y<=0 || map_getcell(m,x,y,CELL_CHKNOPASS)) && (i++)<100){
x=rand()%9-4+bx;
y=rand()%9-4+by;
}
@@ -2895,7 +3071,7 @@ int mob_summonslave(struct mob_data *md2,int *value,int amount,int flag)
y=by;
}
- mob_spawn_dataset(md,"--ja--",class);
+ mob_spawn_dataset(md,"--ja--",class_);
md->bl.m=m;
md->bl.x=x;
md->bl.y=y;
@@ -2976,15 +3152,15 @@ int mob_counttargeted(struct mob_data *md,struct block_list *src,int target_lv)
*MOBskill‚©‚çŠY“–skillid‚Ìskillidx‚ð•Ô‚·
*------------------------------------------
*/
-int mob_skillid2skillidx(int class,int skillid)
+int mob_skillid2skillidx(int class_,int skillid)
{
int i;
- struct mob_skill *ms=mob_db[class].skill;
-
+ struct mob_skill *ms=mob_db[class_].skill;
+
if(ms==NULL)
return -1;
- for(i=0;i<mob_db[class].maxskill;i++){
+ for(i=0;i<mob_db[class_].maxskill;i++){
if(ms[i].skill_id == skillid)
return i;
}
@@ -3023,7 +3199,9 @@ int mobskill_castend_id( int tid, unsigned int tick, int id,int data )
md->skilltimer=-1;
//’¾–Ù‚âó‘ÔˆÙí‚È‚Ç
if(md->sc_data){
- if(md->opt1>0 || md->sc_data[SC_DIVINA].timer != -1 || md->sc_data[SC_ROKISWEIL].timer != -1 || md->sc_data[SC_STEELBODY].timer != -1)
+ if(md->opt1>0 || md->sc_data[SC_DIVINA].timer != -1 ||
+ (!(mob_db[md->class_].mode & 0x20) && md->sc_data[SC_ROKISWEIL].timer != -1) ||
+ md->sc_data[SC_STEELBODY].timer != -1)
return 0;
if(md->sc_data[SC_AUTOCOUNTER].timer != -1 && md->skillid != KN_AUTOCOUNTER) //ƒI[ƒgƒJƒEƒ“ƒ^[
return 0;
@@ -3033,7 +3211,7 @@ int mobskill_castend_id( int tid, unsigned int tick, int id,int data )
return 0;
}
if(md->skillid != NPC_EMOTION)
- md->last_thinktime=tick + battle_get_adelay(&md->bl);
+ md->last_thinktime=tick + status_get_adelay(&md->bl);
if((bl = map_id2bl(md->skilltarget)) == NULL || bl->prev==NULL){ //ƒXƒLƒ‹ƒ^[ƒQƒbƒg‚ª‘¶Ý‚µ‚È‚¢
//printf("mobskill_castend_id nullpo\n");//ƒ^[ƒQƒbƒg‚ª‚¢‚È‚¢‚Æ‚«‚Ínullpo‚¶‚á‚È‚­‚Ä•’Ê‚ÉI—¹
@@ -3043,12 +3221,12 @@ int mobskill_castend_id( int tid, unsigned int tick, int id,int data )
return 0;
if(md->skillid == PR_LEXAETERNA) {
- struct status_change *sc_data = battle_get_sc_data(bl);
+ struct status_change *sc_data = status_get_sc_data(bl);
if(sc_data && (sc_data[SC_FREEZE].timer != -1 || (sc_data[SC_STONE].timer != -1 && sc_data[SC_STONE].val2 == 0)))
return 0;
}
else if(md->skillid == RG_BACKSTAP) {
- int dir = map_calc_dir(&md->bl,bl->x,bl->y),t_dir = battle_get_dir(bl);
+ int dir = map_calc_dir(&md->bl,bl->x,bl->y),t_dir = status_get_dir(bl);
int dist = distance(md->bl.x,md->bl.y,bl->x,bl->y);
if(bl->type != BL_SKILL && (dist == 0 || map_check_dir(dir,t_dir)))
return 0;
@@ -3058,14 +3236,14 @@ int mobskill_castend_id( int tid, unsigned int tick, int id,int data )
return 0;
range = skill_get_range(md->skillid,md->skilllv);
if(range < 0)
- range = battle_get_range(&md->bl) - (range + 1);
+ range = status_get_range(&md->bl) - (range + 1);
if(range + battle_config.mob_skill_add_range < distance(md->bl.x,md->bl.y,bl->x,bl->y))
return 0;
md->skilldelay[md->skillidx]=tick;
if(battle_config.mob_skill_log)
- printf("MOB skill castend skill=%d, class = %d\n",md->skillid,md->class);
+ printf("MOB skill castend skill=%d, class = %d\n",md->skillid,md->class_);
// mob_stop_walking(md,0);
switch( skill_get_nk(md->skillid) )
@@ -3075,8 +3253,8 @@ int mobskill_castend_id( int tid, unsigned int tick, int id,int data )
skill_castend_damage_id(&md->bl,bl,md->skillid,md->skilllv,tick,0);
break;
case 1:// Žx‰‡Œn
- if(!mob_db[md->class].skill[md->skillidx].val[0] &&
- (md->skillid==AL_HEAL || (md->skillid==ALL_RESURRECTION && bl->type != BL_PC)) && battle_check_undead(battle_get_race(bl),battle_get_elem_type(bl)) )
+ if(!mob_db[md->class_].skill[md->skillidx].val[0] &&
+ (md->skillid==AL_HEAL || (md->skillid==ALL_RESURRECTION && bl->type != BL_PC)) && battle_check_undead(status_get_race(bl),status_get_elem_type(bl)) )
skill_castend_damage_id(&md->bl,bl,md->skillid,md->skilllv,tick,0);
else
skill_castend_nodamage_id(&md->bl,bl,md->skillid,md->skilllv,tick,0);
@@ -3094,15 +3272,10 @@ int mobskill_castend_id( int tid, unsigned int tick, int id,int data )
int mobskill_castend_pos( int tid, unsigned int tick, int id,int data )
{
struct mob_data* md=NULL;
- struct block_list *bl;
int range,maxcount;
- //mobskill_castend_id“¯—l‰r¥‚µ‚½Mob‚ª‰r¥Š®—¹Žž‚É‚à‚¤‚¢‚È‚¢‚Æ‚¢‚¤‚̂͂ ‚è‚»‚¤‚Ȃ̂Ånullpo‚©‚眊O
- if((bl=map_id2bl(id))==NULL)
- return 0;
+ nullpo_retr(0, md=(struct mob_data *)map_id2bl(id));
- nullpo_retr(0, md=(struct mob_data *)bl);
-
if( md->bl.type!=BL_MOB || md->bl.prev==NULL )
return 0;
@@ -3111,7 +3284,9 @@ int mobskill_castend_pos( int tid, unsigned int tick, int id,int data )
md->skilltimer=-1;
if(md->sc_data){
- if(md->opt1>0 || md->sc_data[SC_DIVINA].timer != -1 || md->sc_data[SC_ROKISWEIL].timer != -1 || md->sc_data[SC_STEELBODY].timer != -1)
+ if(md->opt1>0 || md->sc_data[SC_DIVINA].timer != -1 ||
+ (!(mob_db[md->class_].mode & 0x20) && md->sc_data[SC_ROKISWEIL].timer != -1) ||
+ md->sc_data[SC_STEELBODY].timer != -1)
return 0;
if(md->sc_data[SC_AUTOCOUNTER].timer != -1 && md->skillid != KN_AUTOCOUNTER) //ƒI[ƒgƒJƒEƒ“ƒ^[
return 0;
@@ -3121,59 +3296,16 @@ int mobskill_castend_pos( int tid, unsigned int tick, int id,int data )
return 0;
}
- if(battle_config.monster_skill_reiteration == 0) {
- range = -1;
- switch(md->skillid) {
- case MG_SAFETYWALL:
- case WZ_FIREPILLAR:
- case HT_SKIDTRAP:
- case HT_LANDMINE:
- case HT_ANKLESNARE:
- case HT_SHOCKWAVE:
- case HT_SANDMAN:
- case HT_FLASHER:
- case HT_FREEZINGTRAP:
- case HT_BLASTMINE:
- case HT_CLAYMORETRAP:
- case PF_SPIDERWEB: /* ƒXƒpƒCƒ_[ƒEƒFƒbƒu */
- range = 0;
- break;
- case AL_PNEUMA:
- case AL_WARP:
- range = 1;
- break;
- }
- if(range >= 0) {
- if(skill_check_unit_range(md->bl.m,md->skillx,md->skilly,range,md->skillid) > 0)
- return 0;
- }
- }
- if(battle_config.monster_skill_nofootset) {
- range = -1;
- switch(md->skillid) {
- case WZ_FIREPILLAR:
- case HT_SKIDTRAP:
- case HT_LANDMINE:
- case HT_ANKLESNARE:
- case HT_SHOCKWAVE:
- case HT_SANDMAN:
- case HT_FLASHER:
- case HT_FREEZINGTRAP:
- case HT_BLASTMINE:
- case HT_CLAYMORETRAP:
- case AM_DEMONSTRATION:
- case PF_SPIDERWEB: /* ƒXƒpƒCƒ_[ƒEƒFƒbƒu */
- range = 1;
- break;
- case AL_WARP:
- range = 0;
- break;
- }
- if(range >= 0) {
- if(skill_check_unit_range2(md->bl.m,md->skillx,md->skilly,range) > 0)
- return 0;
- }
- }
+ if (!battle_config.monster_skill_reiteration &&
+ skill_get_unit_flag (md->skillid) & UF_NOREITERATION &&
+ skill_check_unit_range (md->bl.m, md->skillx, md->skilly, md->skillid, md->skilllv))
+ return 0;
+
+ if(battle_config.monster_skill_nofootset &&
+ skill_get_unit_flag (md->skillid) & UF_NOFOOTSET &&
+ skill_check_unit_range2(&md->bl, md->bl.m, md->skillx, md->skilly, md->skillid, md->skilllv))
+ return 0;
+
if(battle_config.monster_land_skill_limit) {
maxcount = skill_get_maxcount(md->skillid);
@@ -3190,13 +3322,13 @@ int mobskill_castend_pos( int tid, unsigned int tick, int id,int data )
range = skill_get_range(md->skillid,md->skilllv);
if(range < 0)
- range = battle_get_range(&md->bl) - (range + 1);
+ range = status_get_range(&md->bl) - (range + 1);
if(range + battle_config.mob_skill_add_range < distance(md->bl.x,md->bl.y,md->skillx,md->skilly))
return 0;
md->skilldelay[md->skillidx]=tick;
if(battle_config.mob_skill_log)
- printf("MOB skill castend skill=%d, class = %d\n",md->skillid,md->class);
+ printf("MOB skill castend skill=%d, class = %d\n",md->skillid,md->class_);
// mob_stop_walking(md,0);
skill_castend_pos2(&md->bl,md->skillx,md->skilly,md->skillid,md->skilllv,tick,0);
@@ -3216,8 +3348,8 @@ int mobskill_use_id(struct mob_data *md,struct block_list *target,int skill_idx)
int skill_id, skill_lv, forcecast = 0;
nullpo_retr(0, md);
- nullpo_retr(0, ms=&mob_db[md->class].skill[skill_idx]);
-
+ nullpo_retr(0, ms=&mob_db[md->class_].skill[skill_idx]);
+
if( target==NULL && (target=map_id2bl(md->target_id))==NULL )
return 0;
@@ -3229,7 +3361,9 @@ int mobskill_use_id(struct mob_data *md,struct block_list *target,int skill_idx)
// ’¾–Ù‚âˆÙí
if(md->sc_data){
- if(md->opt1>0 || md->sc_data[SC_DIVINA].timer != -1 || md->sc_data[SC_ROKISWEIL].timer != -1 || md->sc_data[SC_STEELBODY].timer != -1)
+ if(md->opt1>0 || md->sc_data[SC_DIVINA].timer != -1 ||
+ (!(mob_db[md->class_].mode & 0x20) && md->sc_data[SC_ROKISWEIL].timer != -1) ||
+ md->sc_data[SC_STEELBODY].timer != -1)
return 0;
if(md->sc_data[SC_AUTOCOUNTER].timer != -1 && md->skillid != KN_AUTOCOUNTER) //ƒI[ƒgƒJƒEƒ“ƒ^[
return 0;
@@ -3244,17 +3378,15 @@ int mobskill_use_id(struct mob_data *md,struct block_list *target,int skill_idx)
if(md->option&2 && skill_id!=TF_HIDING && skill_id!=AS_GRIMTOOTH && skill_id!=RG_BACKSTAP && skill_id!=RG_RAID)
return 0;
- if(map[md->bl.m].flag.gvg && (skill_id == SM_ENDURE || skill_id == AL_TELEPORT || skill_id == AL_WARP ||
- skill_id == WZ_ICEWALL || skill_id == TF_BACKSLIDING))
+ if(map[md->bl.m].flag.gvg && skill_db[skill_id].nocast & 4)
return 0;
-
if(skill_get_inf2(skill_id)&0x200 && md->bl.id == target->id)
return 0;
// ŽË’ö‚ÆáŠQ•¨ƒ`ƒFƒbƒN
range = skill_get_range(skill_id,skill_lv);
if(range < 0)
- range = battle_get_range(&md->bl) - (range + 1);
+ range = status_get_range(&md->bl) - (range + 1);
if(!battle_check_range(&md->bl,target,range))
return 0;
@@ -3266,7 +3398,7 @@ int mobskill_use_id(struct mob_data *md,struct block_list *target,int skill_idx)
switch(skill_id){ /* ‰½‚©“ÁŽê‚Ȉ—‚ª•K—v */
case ALL_RESURRECTION: /* ƒŠƒUƒŒƒNƒVƒ‡ƒ“ */
- if(target->type != BL_PC && battle_check_undead(battle_get_race(target),battle_get_elem_type(target))){ /* “G‚ªƒAƒ“ƒfƒbƒh‚È‚ç */
+ if(target->type != BL_PC && battle_check_undead(status_get_race(target),status_get_elem_type(target))){ /* “G‚ªƒAƒ“ƒfƒbƒh‚È‚ç */
forcecast=1; /* ƒ^[ƒ“ƒAƒ“ƒfƒbƒg‚Æ“¯‚¶‰r¥ŽžŠÔ */
casttime=skill_castfix(&md->bl, skill_get_cast(PR_TURNUNDEAD,skill_lv) );
}
@@ -3276,10 +3408,15 @@ int mobskill_use_id(struct mob_data *md,struct block_list *target,int skill_idx)
case SA_SPELLBREAKER:
forcecast=1;
break;
+ case NPC_SUMMONSLAVE:
+ case NPC_SUMMONMONSTER:
+ if(md->master_id!=0)
+ return 0;
+ break;
}
if(battle_config.mob_skill_log)
- printf("MOB skill use target_id=%d skill=%d lv=%d cast=%d, class = %d\n",target->id,skill_id,skill_lv,casttime,md->class);
+ printf("MOB skill use target_id=%d skill=%d lv=%d cast=%d, class = %d\n",target->id,skill_id,skill_lv,casttime,md->class_);
if(casttime>0 || forcecast){ // ‰r¥‚ª•K—v
// struct mob_data *md2;
@@ -3288,8 +3425,9 @@ int mobskill_use_id(struct mob_data *md,struct block_list *target,int skill_idx)
md->bl.id, target->id, 0,0, skill_id,casttime);
// ‰r¥”½‰žƒ‚ƒ“ƒXƒ^[
-/* if( target->type==BL_MOB && mob_db[(md2=(struct mob_data *)target)->class].mode&0x10 &&
- md2->state.state!=MS_ATTACK){
+ // future homunculus support?
+/* if(md->master_id && target->type==BL_MOB && (md2=(struct mob_data *)target) &&
+ mob_db[md2->class_].mode&0x10 && md2->state.state!=MS_ATTACK){
md2->target_id=md->bl.id;
md->state.targettype = ATTACKABLE;
md2->min_chase=13;
@@ -3307,7 +3445,7 @@ int mobskill_use_id(struct mob_data *md,struct block_list *target,int skill_idx)
md->skillidx = skill_idx;
if(!(battle_config.monster_cloak_check_type&2) && md->sc_data[SC_CLOAKING].timer != -1 && md->skillid != AS_CLOAKING)
- skill_status_change_end(&md->bl,SC_CLOAKING,-1);
+ status_change_end(&md->bl,SC_CLOAKING,-1);
if( casttime>0 ){
md->skilltimer =
@@ -3332,7 +3470,7 @@ int mobskill_use_pos( struct mob_data *md,
int skill_id, skill_lv;
nullpo_retr(0, md);
- nullpo_retr(0, ms=&mob_db[md->class].skill[skill_idx]);
+ nullpo_retr(0, ms=&mob_db[md->class_].skill[skill_idx]);
if( md->bl.prev==NULL )
return 0;
@@ -3342,7 +3480,9 @@ int mobskill_use_pos( struct mob_data *md,
//’¾–Ù‚âó‘ÔˆÙí‚È‚Ç
if(md->sc_data){
- if(md->opt1>0 || md->sc_data[SC_DIVINA].timer != -1 || md->sc_data[SC_ROKISWEIL].timer != -1 || md->sc_data[SC_STEELBODY].timer != -1)
+ if(md->opt1>0 || md->sc_data[SC_DIVINA].timer != -1 ||
+ (!(mob_db[md->class_].mode & 0x20) && md->sc_data[SC_ROKISWEIL].timer != -1) ||
+ md->sc_data[SC_STEELBODY].timer != -1)
return 0;
if(md->sc_data[SC_AUTOCOUNTER].timer != -1 && md->skillid != KN_AUTOCOUNTER) //ƒI[ƒgƒJƒEƒ“ƒ^[
return 0;
@@ -3366,7 +3506,7 @@ int mobskill_use_pos( struct mob_data *md,
bl.y = skill_y;
range = skill_get_range(skill_id,skill_lv);
if(range < 0)
- range = battle_get_range(&md->bl) - (range + 1);
+ range = status_get_range(&md->bl) - (range + 1);
if(!battle_check_range(&md->bl,&bl,range))
return 0;
@@ -3377,7 +3517,7 @@ int mobskill_use_pos( struct mob_data *md,
if(battle_config.mob_skill_log)
printf("MOB skill use target_pos=(%d,%d) skill=%d lv=%d cast=%d, class = %d\n",
- skill_x,skill_y,skill_id,skill_lv,casttime,md->class);
+ skill_x,skill_y,skill_id,skill_lv,casttime,md->class_);
if( casttime>0 ) { // A cast time is required.
mob_stop_walking(md,0); // •às’âŽ~
@@ -3396,7 +3536,7 @@ int mobskill_use_pos( struct mob_data *md,
md->skilllv = skill_lv;
md->skillidx = skill_idx;
if(!(battle_config.monster_cloak_check_type&2) && md->sc_data[SC_CLOAKING].timer != -1)
- skill_status_change_end(&md->bl,SC_CLOAKING,-1);
+ status_change_end(&md->bl,SC_CLOAKING,-1);
if( casttime>0 ){
md->skilltimer =
add_timer( gettick()+casttime, mobskill_castend_pos, md->bl.id, 0 );
@@ -3428,7 +3568,7 @@ int mob_getfriendhpltmaxrate_sub(struct block_list *bl,va_list ap)
return 0;
rate=va_arg(ap,int);
fr=va_arg(ap,struct mob_data **);
- if( md->hp < mob_db[md->class].max_hp*rate/100 )
+ if( md->hp < mob_db[md->class_].max_hp*rate/100 )
(*fr)=md;
return 0;
}
@@ -3500,9 +3640,9 @@ int mobskill_use(struct mob_data *md,unsigned int tick,int event)
int i,max_hp;
nullpo_retr(0, md);
- nullpo_retr(0, ms = mob_db[md->class].skill);
+ nullpo_retr(0, ms = mob_db[md->class_].skill);
- max_hp = battle_get_max_hp(&md->bl);
+ max_hp = status_get_max_hp(&md->bl);
if(battle_config.mob_skill_use == 0 || md->skilltimer != -1)
return 0;
@@ -3513,7 +3653,7 @@ int mobskill_use(struct mob_data *md,unsigned int tick,int event)
if(md->sc_data[SC_SELFDESTRUCTION].timer!=-1) //Ž©”š’†‚ÍƒXƒLƒ‹‚ðŽg‚í‚È‚¢
return 0;
- for(i=0;i<mob_db[md->class].maxskill;i++){
+ for(i=0;i<mob_db[md->class_].maxskill;i++){
int c2=ms[i].cond2,flag=0;
struct mob_data *fmd=NULL;
@@ -3579,24 +3719,24 @@ int mobskill_use(struct mob_data *md,unsigned int tick,int event)
continue;
// Ž©•ª‚ÌŽüˆÍ
if( ms[i].target>=MST_AROUND1 ){
- int bx=x, by=y, i=0, c, m=bl->m, r=ms[i].target-MST_AROUND1;
+ int bx=x, by=y, i=0, m=bl->m, r=ms[i].target-MST_AROUND1;
do{
bx=x + rand()%(r*2+3) - r;
by=y + rand()%(r*2+3) - r;
}while( ( bx<=0 || by<=0 || bx>=map[m].xs || by>=map[m].ys ||
- ((c=read_gat(m,bx,by))==1 || c==5) ) && (i++)<1000);
+ map_getcell(m,bx,by,CELL_CHKNOPASS)) && (i++)<1000);
if(i<1000){
x=bx; y=by;
}
}
// ‘ŠŽè‚ÌŽüˆÍ
if( ms[i].target>=MST_AROUND5 ){
- int bx=x, by=y, i=0, c, m=bl->m, r=(ms[i].target-MST_AROUND5)+1;
+ int bx=x, by=y, i=0,m=bl->m, r=(ms[i].target-MST_AROUND5)+1;
do{
bx=x + rand()%(r*2+1) - r;
by=y + rand()%(r*2+1) - r;
}while( ( bx<=0 || by<=0 || bx>=map[m].xs || by>=map[m].ys ||
- ((c=read_gat(m,bx,by))==1 || c==5) ) && (i++)<1000);
+ map_getcell(m,bx,by,CELL_CHKNOPASS)) && (i++)<1000);
if(i<1000){
x=bx; y=by;
}
@@ -3645,27 +3785,30 @@ int mobskill_event(struct mob_data *md,int flag)
int mob_gvmobcheck(struct map_session_data *sd, struct block_list *bl)
{
struct mob_data *md=NULL;
-
+
nullpo_retr(0,sd);
nullpo_retr(0,bl);
-
+
if(bl->type==BL_MOB && (md=(struct mob_data *)bl) &&
- (md->class == 1288 || md->class == 1287 || md->class == 1286 || md->class == 1285))
+ (md->class_ == 1288 || md->class_ == 1287 || md->class_ == 1286 || md->class_ == 1285))
{
struct guild_castle *gc=guild_mapname2gc(map[sd->bl.m].name);
struct guild *g=guild_search(sd->status.guild_id);
- if(g == NULL && md->class == 1288)
+ if(g == NULL && md->class_ == 1288)
return 0;//ƒMƒ‹ƒh–¢‰Á“ü‚È‚çƒ_ƒ[ƒW–³‚µ
else if(gc != NULL && !map[sd->bl.m].flag.gvg)
return 0;//Ô“à‚ÅGv‚¶‚á‚È‚¢‚Æ‚«‚̓_ƒ[ƒW‚È‚µ
- else if(g && gc != NULL && g->guild_id == gc->guild_id)
- return 0;//Ž©è—̃Mƒ‹ƒh‚̃Gƒ“ƒy‚È‚çƒ_ƒ[ƒW–³‚µ
- else if(g && guild_checkskill(g,GD_APPROVAL) <= 0 && md->class == 1288)
- return 0;//³‹KƒMƒ‹ƒh³”F‚ª‚È‚¢‚ƃ_ƒ[ƒW–³‚µ
-
+ else if(g) {
+ if (gc != NULL && g->guild_id == gc->guild_id)
+ return 0;//Ž©è—̃Mƒ‹ƒh‚̃Gƒ“ƒy‚È‚çƒ_ƒ[ƒW–³‚µ
+ else if(guild_checkskill(g,GD_APPROVAL) <= 0 && md->class_ == 1288)
+ return 0;//³‹KƒMƒ‹ƒh³”F‚ª‚È‚¢‚ƃ_ƒ[ƒW–³‚µ
+ else if (gc && guild_check_alliance(gc->guild_id, g->guild_id, 0) == 1)
+ return 0; // “¯–¿‚È‚çƒ_ƒ[ƒW–³‚µ
+ }
}
-
+
return 1;
}
/*==========================================
@@ -3692,53 +3835,53 @@ int mobskill_deltimer(struct mob_data *md )
* Since un-setting [ mob ] up was used, it is an initial provisional value setup.
*------------------------------------------
*/
-static int mob_makedummymobdb(int class)
+static int mob_makedummymobdb(int class_)
{
int i;
- sprintf(mob_db[class].name,"mob%d",class);
- sprintf(mob_db[class].jname,"mob%d",class);
- mob_db[class].lv=1;
- mob_db[class].max_hp=1000;
- mob_db[class].max_sp=1;
- mob_db[class].base_exp=2;
- mob_db[class].job_exp=1;
- mob_db[class].range=1;
- mob_db[class].atk1=7;
- mob_db[class].atk2=10;
- mob_db[class].def=0;
- mob_db[class].mdef=0;
- mob_db[class].str=1;
- mob_db[class].agi=1;
- mob_db[class].vit=1;
- mob_db[class].int_=1;
- mob_db[class].dex=6;
- mob_db[class].luk=2;
- mob_db[class].range2=10;
- mob_db[class].range3=10;
- mob_db[class].size=0;
- mob_db[class].race=0;
- mob_db[class].element=0;
- mob_db[class].mode=0;
- mob_db[class].speed=300;
- mob_db[class].adelay=1000;
- mob_db[class].amotion=500;
- mob_db[class].dmotion=500;
- mob_db[class].dropitem[0].nameid=909; // Jellopy
- mob_db[class].dropitem[0].p=1000;
- for(i=1;i<8;i++){
- mob_db[class].dropitem[i].nameid=0;
- mob_db[class].dropitem[i].p=0;
+ sprintf(mob_db[class_].name,"mob%d",class_);
+ sprintf(mob_db[class_].jname,"mob%d",class_);
+ mob_db[class_].lv=1;
+ mob_db[class_].max_hp=1000;
+ mob_db[class_].max_sp=1;
+ mob_db[class_].base_exp=2;
+ mob_db[class_].job_exp=1;
+ mob_db[class_].range=1;
+ mob_db[class_].atk1=7;
+ mob_db[class_].atk2=10;
+ mob_db[class_].def=0;
+ mob_db[class_].mdef=0;
+ mob_db[class_].str=1;
+ mob_db[class_].agi=1;
+ mob_db[class_].vit=1;
+ mob_db[class_].int_=1;
+ mob_db[class_].dex=6;
+ mob_db[class_].luk=2;
+ mob_db[class_].range2=10;
+ mob_db[class_].range3=10;
+ mob_db[class_].size=0;
+ mob_db[class_].race=0;
+ mob_db[class_].element=0;
+ mob_db[class_].mode=0;
+ mob_db[class_].speed=300;
+ mob_db[class_].adelay=1000;
+ mob_db[class_].amotion=500;
+ mob_db[class_].dmotion=500;
+ //mob_db[class_].dropitem[0].nameid=909; // Jellopy
+ //mob_db[class_].dropitem[0].p=1000;
+ for(i=1;i<10;i++){ // 8-> 10 Lupus
+ mob_db[class_].dropitem[i].nameid=0;
+ mob_db[class_].dropitem[i].p=0;
}
// Item1,Item2
- mob_db[class].mexp=0;
- mob_db[class].mexpper=0;
+ mob_db[class_].mexp=0;
+ mob_db[class_].mexpper=0;
for(i=0;i<3;i++){
- mob_db[class].mvpitem[i].nameid=0;
- mob_db[class].mvpitem[i].p=0;
+ mob_db[class_].mvpitem[i].nameid=0;
+ mob_db[class_].mvpitem[i].p=0;
}
for(i=0;i<MAX_RANDOMMONSTER;i++)
- mob_db[class].summonper[i]=0;
+ mob_db[class_].summonper[i]=0;
return 0;
}
@@ -3764,13 +3907,13 @@ static int mob_readdb(void)
return -1;
}
while(fgets(line,1020,fp)){
- int class,i;
- char *str[55],*p,*np;
+ int class_,i;
+ char *str[60],*p,*np; // 55->60 Lupus
if(line[0] == '/' && line[1] == '/')
continue;
- for(i=0,p=line;i<55;i++){
+ for(i=0,p=line;i<60;i++){
if((np=strchr(p,','))!=NULL){
str[i]=p;
*np=0;
@@ -3779,113 +3922,122 @@ static int mob_readdb(void)
str[i]=p;
}
- class=atoi(str[0]);
- if(class<=1000 || class>2000)
+ class_=atoi(str[0]);
+ if(class_<=1000 || class_>MAX_MOB_DB)
continue;
- mob_db[class].view_class=class;
- memcpy(mob_db[class].name,str[1],24);
- memcpy(mob_db[class].jname,str[2],24);
- mob_db[class].lv=atoi(str[3]);
- mob_db[class].max_hp=atoi(str[4]);
- mob_db[class].max_sp=atoi(str[5]);
-
- mob_db[class].base_exp=atoi(str[6]);
- if(mob_db[class].base_exp < 0)
- mob_db[class].base_exp = 0;
- else if(mob_db[class].base_exp > 0 && (mob_db[class].base_exp*battle_config.base_exp_rate/100 > 1000000000 ||
- mob_db[class].base_exp*battle_config.base_exp_rate/100 < 0))
- mob_db[class].base_exp=1000000000;
- else
- mob_db[class].base_exp*= battle_config.base_exp_rate/100;
-
- mob_db[class].job_exp=atoi(str[7]);
- if(mob_db[class].job_exp < 0)
- mob_db[class].job_exp = 0;
- else if(mob_db[class].job_exp > 0 && (mob_db[class].job_exp*battle_config.job_exp_rate/100 > 1000000000 ||
- mob_db[class].job_exp*battle_config.job_exp_rate/100 < 0))
- mob_db[class].job_exp=1000000000;
- else
- mob_db[class].job_exp*=battle_config.job_exp_rate/100;
-
- mob_db[class].range=atoi(str[8]);
- mob_db[class].atk1=atoi(str[9]);
- mob_db[class].atk2=atoi(str[10]);
- mob_db[class].def=atoi(str[11]);
- mob_db[class].mdef=atoi(str[12]);
- mob_db[class].str=atoi(str[13]);
- mob_db[class].agi=atoi(str[14]);
- mob_db[class].vit=atoi(str[15]);
- mob_db[class].int_=atoi(str[16]);
- mob_db[class].dex=atoi(str[17]);
- mob_db[class].luk=atoi(str[18]);
- mob_db[class].range2=atoi(str[19]);
- mob_db[class].range3=atoi(str[20]);
- mob_db[class].size=atoi(str[21]);
- mob_db[class].race=atoi(str[22]);
- mob_db[class].element=atoi(str[23]);
- mob_db[class].mode=atoi(str[24]);
- mob_db[class].speed=atoi(str[25]);
- mob_db[class].adelay=atoi(str[26]);
- mob_db[class].amotion=atoi(str[27]);
- mob_db[class].dmotion=atoi(str[28]);
-
- for(i=0;i<8;i++){
+ mob_db[class_].view_class=class_;
+ memcpy(mob_db[class_].name,str[1],24);
+ memcpy(mob_db[class_].jname,str[2],24);
+ mob_db[class_].lv=atoi(str[3]);
+ mob_db[class_].max_hp=atoi(str[4]);
+ mob_db[class_].max_sp=atoi(str[5]);
+
+ mob_db[class_].base_exp = atoi(str[6]);
+ if (mob_db[class_].base_exp <= 0)
+ mob_db[class_].base_exp = 0;
+ else if (mob_db[class_].base_exp * battle_config.base_exp_rate / 100 > 1000000000 ||
+ mob_db[class_].base_exp * battle_config.base_exp_rate / 100 < 0)
+ mob_db[class_].base_exp = 1000000000;
+ else {
+ mob_db[class_].base_exp = mob_db[class_].base_exp * battle_config.base_exp_rate / 100;
+ if (mob_db[class_].base_exp < 1)
+ mob_db[class_].base_exp = 1;
+ }
+
+ mob_db[class_].job_exp = atoi(str[7]);
+ if (mob_db[class_].job_exp <= 0)
+ mob_db[class_].job_exp = 0;
+ else if (mob_db[class_].job_exp * battle_config.job_exp_rate / 100 > 1000000000 ||
+ mob_db[class_].job_exp * battle_config.job_exp_rate / 100 < 0)
+ mob_db[class_].job_exp = 1000000000;
+ else {
+ mob_db[class_].job_exp = mob_db[class_].job_exp * battle_config.job_exp_rate / 100;
+ if (mob_db[class_].job_exp < 1)
+ mob_db[class_].job_exp = 1;
+ }
+
+ mob_db[class_].range=atoi(str[8]);
+ mob_db[class_].atk1=atoi(str[9]);
+ mob_db[class_].atk2=atoi(str[10]);
+ mob_db[class_].def=atoi(str[11]);
+ mob_db[class_].mdef=atoi(str[12]);
+ mob_db[class_].str=atoi(str[13]);
+ mob_db[class_].agi=atoi(str[14]);
+ mob_db[class_].vit=atoi(str[15]);
+ mob_db[class_].int_=atoi(str[16]);
+ mob_db[class_].dex=atoi(str[17]);
+ mob_db[class_].luk=atoi(str[18]);
+ mob_db[class_].range2=atoi(str[19]);
+ mob_db[class_].range3=atoi(str[20]);
+ mob_db[class_].size=atoi(str[21]);
+ mob_db[class_].race=atoi(str[22]);
+ mob_db[class_].element=atoi(str[23]);
+ mob_db[class_].mode=atoi(str[24]);
+ mob_db[class_].speed=atoi(str[25]);
+ mob_db[class_].adelay=atoi(str[26]);
+ mob_db[class_].amotion=atoi(str[27]);
+ mob_db[class_].dmotion=atoi(str[28]);
+
+ for(i=0;i<10;i++){ // 8 -> 10 Lupus
int rate = 0,type,ratemin,ratemax;
- mob_db[class].dropitem[i].nameid=atoi(str[29+i*2]);
- type = itemdb_type(mob_db[class].dropitem[i].nameid);
- if (type == 0) { // Added [Valaris]
- rate = battle_config.item_rate_heal;
+ mob_db[class_].dropitem[i].nameid=atoi(str[29+i*2]);
+ type = itemdb_type(mob_db[class_].dropitem[i].nameid);
+ if (type == 0) {
+ rate = battle_config.item_rate_heal * atoi(str[30+i*2]) / 100; //fix by Yor
ratemin = battle_config.item_drop_heal_min;
ratemax = battle_config.item_drop_heal_max;
}
else if (type == 2) {
- rate = battle_config.item_rate_use;
+ rate = battle_config.item_rate_use * atoi(str[30+i*2]) / 100; //fix by Yor
ratemin = battle_config.item_drop_use_min;
ratemax = battle_config.item_drop_use_max; // End
}
else if (type == 4 || type == 5 || type == 8) { // Changed to include Pet Equip
- rate = battle_config.item_rate_equip;
+ rate = battle_config.item_rate_equip * atoi(str[30+i*2]) / 100;
ratemin = battle_config.item_drop_equip_min;
ratemax = battle_config.item_drop_equip_max;
}
else if (type == 6) {
- rate = battle_config.item_rate_card;
+ rate = battle_config.item_rate_card * atoi(str[30+i*2]) / 100;
ratemin = battle_config.item_drop_card_min;
ratemax = battle_config.item_drop_card_max;
}
else {
- rate = battle_config.item_rate_common;
+ rate = battle_config.item_rate_common * atoi(str[30+i*2]) / 100;
ratemin = battle_config.item_drop_common_min;
ratemax = battle_config.item_drop_common_max;
}
- rate = (rate / 100) * atoi(str[30+i*2]);
- rate = (rate < ratemin)? ratemin: (rate > ratemax)? ratemax: rate;
- mob_db[class].dropitem[i].p = rate;
+ mob_db[class_].dropitem[i].p = (rate < ratemin) ? ratemin : (rate > ratemax) ? ratemax: rate;
}
- // Item1,Item2
- mob_db[class].mexp=atoi(str[45])*battle_config.mvp_exp_rate/100;
- mob_db[class].mexpper=atoi(str[46]);
+ // MVP EXP Bonus, Chance: MEXP,ExpPer
+ mob_db[class_].mexp=atoi(str[49])*battle_config.mvp_exp_rate/100;
+ mob_db[class_].mexpper=atoi(str[50]);
+ // MVP Drops: MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per
for(i=0;i<3;i++){
- mob_db[class].mvpitem[i].nameid=atoi(str[47+i*2]);
- mob_db[class].mvpitem[i].p=atoi(str[48+i*2])*battle_config.mvp_item_rate/100;
+ int rate=atoi(str[52+i*2])*battle_config.mvp_item_rate/100; //idea of the fix from Freya
+ mob_db[class_].mvpitem[i].nameid=atoi(str[51+i*2]);
+ mob_db[class_].mvpitem[i].p= (rate < battle_config.item_drop_mvp_min)
+ ? battle_config.item_drop_mvp_min : (rate > battle_config.item_drop_mvp_max)
+ ? battle_config.item_drop_mvp_max : rate;
}
for(i=0;i<MAX_RANDOMMONSTER;i++)
- mob_db[class].summonper[i]=0;
- mob_db[class].maxskill=0;
-
- mob_db[class].sex=0;
- mob_db[class].hair=0;
- mob_db[class].hair_color=0;
- mob_db[class].weapon=0;
- mob_db[class].shield=0;
- mob_db[class].head_top=0;
- mob_db[class].head_mid=0;
- mob_db[class].head_buttom=0;
- mob_db[class].clothes_color=0; //Add for player monster dye - Valaris
+ mob_db[class_].summonper[i]=0;
+ mob_db[class_].maxskill=0;
+
+ mob_db[class_].sex=0;
+ mob_db[class_].hair=0;
+ mob_db[class_].hair_color=0;
+ mob_db[class_].weapon=0;
+ mob_db[class_].shield=0;
+ mob_db[class_].head_top=0;
+ mob_db[class_].head_mid=0;
+ mob_db[class_].head_buttom=0;
+ mob_db[class_].clothes_color=0; //Add for player monster dye - Valaris
}
fclose(fp);
- printf("read %s done\n",filename[i]);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n",filename[i]);
+ ShowStatus(tmp_output);
}
return 0;
}
@@ -3899,7 +4051,7 @@ static int mob_readdb_mobavail(void)
FILE *fp;
char line[1024];
int ln=0;
- int class,j,k;
+ int class_,j,k;
char *str[20],*p,*np;
if( (fp=fopen("db/mob_avail.txt","r"))==NULL ){
@@ -3918,39 +4070,42 @@ static int mob_readdb_mobavail(void)
*np=0;
p=np+1;
} else
- str[j]=p;
- }
+ str[j]=p;
+ }
if(str[0]==NULL)
continue;
- class=atoi(str[0]);
-
- if(class<=1000 || class>2000) // ’l‚ªˆÙí‚Ȃ爗‚µ‚È‚¢B
+ class_=atoi(str[0]);
+ if(class_<=1000 || class_>MAX_MOB_DB) // ’l‚ªˆÙí‚Ȃ爗‚µ‚È‚¢B
continue;
+
k=atoi(str[1]);
- if(k >= 0)
- mob_db[class].view_class=k;
-
- if((mob_db[class].view_class < 24) || (mob_db[class].view_class > 4000)) {
- mob_db[class].sex=atoi(str[2]);
- mob_db[class].hair=atoi(str[3]);
- mob_db[class].hair_color=atoi(str[4]);
- mob_db[class].weapon=atoi(str[5]);
- mob_db[class].shield=atoi(str[6]);
- mob_db[class].head_top=atoi(str[7]);
- mob_db[class].head_mid=atoi(str[8]);
- mob_db[class].head_buttom=atoi(str[9]);
- mob_db[class].option=atoi(str[10])&~0x46;
- mob_db[class].clothes_color=atoi(str[11]); // Monster player dye option - Valaris
+ if(k < 0)
+ continue;
+ if (j > 3 && k > 23 && k < 69)
+ k += 3977; // advanced job/baby class
+ mob_db[class_].view_class=k;
+
+ if((k < 24) || (k > 4000)) {
+ mob_db[class_].sex=atoi(str[2]);
+ mob_db[class_].hair=atoi(str[3]);
+ mob_db[class_].hair_color=atoi(str[4]);
+ mob_db[class_].weapon=atoi(str[5]);
+ mob_db[class_].shield=atoi(str[6]);
+ mob_db[class_].head_top=atoi(str[7]);
+ mob_db[class_].head_mid=atoi(str[8]);
+ mob_db[class_].head_buttom=atoi(str[9]);
+ mob_db[class_].option=atoi(str[10])&~0x46;
+ mob_db[class_].clothes_color=atoi(str[11]); // Monster player dye option - Valaris
}
-
- else if(atoi(str[2]) > 0) mob_db[class].equip=atoi(str[2]); // mob equipment [Valaris]
+ else if(atoi(str[2]) > 0) mob_db[class_].equip=atoi(str[2]); // mob equipment [Valaris]
ln++;
}
fclose(fp);
- printf("read db/mob_avail.txt done (count=%d)\n",ln);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"db/mob_avail.txt");
+ ShowStatus(tmp_output);
return 0;
}
@@ -3978,7 +4133,7 @@ static int mob_read_randommonster(void)
return -1;
}
while(fgets(line,1020,fp)){
- int class,per;
+ int class_,per;
if(line[0] == '/' && line[1] == '/')
continue;
memset(str,0,sizeof(str));
@@ -3991,13 +4146,14 @@ static int mob_read_randommonster(void)
if(str[0]==NULL || str[2]==NULL)
continue;
- class = atoi(str[0]);
+ class_ = atoi(str[0]);
per=atoi(str[2]);
- if((class>1000 && class<=2000) || class==0)
- mob_db[class].summonper[i]=per;
+ if((class_>1000 && class_<=MAX_MOB_DB) || class_==0)
+ mob_db[class_].summonper[i]=per;
}
fclose(fp);
- printf("read %s done\n",mobfile[i]);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n",mobfile[i]);
+ ShowStatus(tmp_output);
}
return 0;
}
@@ -4116,7 +4272,10 @@ static int mob_readskilldb(void)
ms->state=state[j].id;
}
ms->skill_id=atoi(sp[3]);
- ms->skill_lv=atoi(sp[4]);
+ j=atoi(sp[4]);
+ if (j<=0 || j>MAX_SKILL_DB)
+ continue;
+ ms->skill_lv=j;
ms->permillage=atoi(sp[5]);
ms->casttime=atoi(sp[6]);
ms->delay=atoi(sp[7]);
@@ -4149,21 +4308,61 @@ static int mob_readskilldb(void)
mob_db[mob_id].maxskill=i+1;
}
fclose(fp);
- printf("read %s done\n",filename[x]);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n",filename[x]);
+ ShowStatus(tmp_output);
}
return 0;
}
-
-void mob_reload(void)
+/*==========================================
+ * db/mob_race_db.txt reading
+ *------------------------------------------
+ */
+static int mob_readdb_race(void)
{
- /*
+ FILE *fp;
+ char line[1024];
+ int race,j,k;
+ char *str[20],*p,*np;
- <empty monster database>
- mob_read();
+ if( (fp=fopen("db/mob_race2_db.txt","r"))==NULL ){
+ printf("can't read db/mob_race2_db.txt\n");
+ return -1;
+ }
+
+ while(fgets(line,1020,fp)){
+ if(line[0]=='/' && line[1]=='/')
+ continue;
+ memset(str,0,sizeof(str));
- */
+ for(j=0,p=line;j<12;j++){
+ if((np=strchr(p,','))!=NULL){
+ str[j]=p;
+ *np=0;
+ p=np+1;
+ } else
+ str[j]=p;
+ }
+ if(str[0]==NULL)
+ continue;
+
+ race=atoi(str[0]);
+ if (race < 0 || race >= MAX_MOB_RACE_DB)
+ continue;
- do_init_mob();
+ for (j=1; j<20; j++) {
+ if (!str[j])
+ break;
+ k=atoi(str[j]);
+ if (k < 1000 || k > MAX_MOB_DB)
+ continue;
+ mob_db[k].race2 = race;
+ //mob_race_db[race][j] = k;
+ }
+ }
+ fclose(fp);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/mob_race2_db.txt");
+ ShowStatus(tmp_output);
+ return 0;
}
#ifndef TXT_ONLY
@@ -4174,11 +4373,12 @@ void mob_reload(void)
static int mob_read_sqldb(void)
{
char line[1024];
- int i,class,ln=0;
- char *str[55],*p,*np;
-
+ int i,class_;
+ long unsigned int ln=0;
+ char *str[60],*p,*np; // 55->60 Lupus
+
memset(mob_db,0,sizeof(mob_db));
-
+
sprintf (tmp_sql, "SELECT * FROM `%s`",mob_db_db);
if(mysql_query(&mmysql_handle, tmp_sql) ) {
printf("DB server Error (select %s to Memory)- %s\n",mob_db_db,mysql_error(&mmysql_handle) );
@@ -4186,7 +4386,7 @@ static int mob_read_sqldb(void)
sql_res = mysql_store_result(&mmysql_handle);
if (sql_res) {
while((sql_row = mysql_fetch_row(sql_res))){
- sprintf(line,"%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s",
+ sprintf(line,"%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s",
sql_row[0],sql_row[1],sql_row[2],sql_row[3],sql_row[4],
sql_row[5],sql_row[6],sql_row[7],sql_row[8],sql_row[9],
sql_row[10],sql_row[11],sql_row[12],sql_row[13],sql_row[14],
@@ -4197,9 +4397,10 @@ static int mob_read_sqldb(void)
sql_row[35],sql_row[36],sql_row[37],sql_row[38],sql_row[39],
sql_row[40],sql_row[41],sql_row[42],sql_row[43],sql_row[44],
sql_row[45],sql_row[46],sql_row[47],sql_row[48],sql_row[49],
- sql_row[50],sql_row[51],sql_row[52]);
+ sql_row[50],sql_row[51],sql_row[52],sql_row[53],sql_row[54],
+ sql_row[55],sql_row[56]);
- for(i=0,p=line;i<55;i++){
+ for(i=0,p=line;i<57;i++){
if((np=strchr(p,','))!=NULL){
str[i]=p;
*np=0;
@@ -4207,109 +4408,141 @@ static int mob_read_sqldb(void)
} else
str[i]=p;
}
-
- class=atoi(str[0]);
- if(class<=1000 || class>2000)
+
+ class_=atoi(str[0]);
+ if(class_<=1000 || class_>MAX_MOB_DB)
continue;
-
+
ln++;
-
- mob_db[class].view_class=class;
- memcpy(mob_db[class].name,str[1],24);
- memcpy(mob_db[class].jname,str[2],24);
- mob_db[class].lv=atoi(str[3]);
- mob_db[class].max_hp=atoi(str[4]);
- mob_db[class].max_sp=atoi(str[5]);
- mob_db[class].base_exp=atoi(str[6])*
- battle_config.base_exp_rate/100;
- if(mob_db[class].base_exp <= 0)
- mob_db[class].base_exp = 1;
- mob_db[class].job_exp=atoi(str[7])*
- battle_config.job_exp_rate/100;
- if(mob_db[class].job_exp <= 0)
- mob_db[class].job_exp = 1;
- mob_db[class].range=atoi(str[8]);
- mob_db[class].atk1=atoi(str[9]);
- mob_db[class].atk2=atoi(str[10]);
- mob_db[class].def=atoi(str[11]);
- mob_db[class].mdef=atoi(str[12]);
- mob_db[class].str=atoi(str[13]);
- mob_db[class].agi=atoi(str[14]);
- mob_db[class].vit=atoi(str[15]);
- mob_db[class].int_=atoi(str[16]);
- mob_db[class].dex=atoi(str[17]);
- mob_db[class].luk=atoi(str[18]);
- mob_db[class].range2=atoi(str[19]);
- mob_db[class].range3=atoi(str[20]);
- mob_db[class].size=atoi(str[21]);
- mob_db[class].race=atoi(str[22]);
- mob_db[class].element=atoi(str[23]);
- mob_db[class].mode=atoi(str[24]);
- mob_db[class].speed=atoi(str[25]);
- mob_db[class].adelay=atoi(str[26]);
- mob_db[class].amotion=atoi(str[27]);
- mob_db[class].dmotion=atoi(str[28]);
-
- for(i=0;i<8;i++){
+
+ mob_db[class_].view_class=class_;
+ memcpy(mob_db[class_].name,str[1],24);
+ memcpy(mob_db[class_].jname,str[2],24);
+ mob_db[class_].lv=atoi(str[3]);
+ mob_db[class_].max_hp=atoi(str[4]);
+ mob_db[class_].max_sp=atoi(str[5]);
+
+ mob_db[class_].base_exp = atoi(str[6]);
+ if (mob_db[class_].base_exp <= 0)
+ mob_db[class_].base_exp = 0;
+ else if (mob_db[class_].base_exp * battle_config.base_exp_rate / 100 > 1000000000 ||
+ mob_db[class_].base_exp * battle_config.base_exp_rate / 100 < 0)
+ mob_db[class_].base_exp = 1000000000;
+ else {
+ mob_db[class_].base_exp = mob_db[class_].base_exp * battle_config.base_exp_rate / 100;
+ if (mob_db[class_].base_exp < 1)
+ mob_db[class_].base_exp = 1;
+ }
+ mob_db[class_].job_exp = atoi(str[7]);
+ if (mob_db[class_].job_exp <= 0)
+ mob_db[class_].job_exp = 0;
+ else if (mob_db[class_].job_exp * battle_config.job_exp_rate / 100 > 1000000000 ||
+ mob_db[class_].job_exp * battle_config.job_exp_rate / 100 < 0)
+ mob_db[class_].job_exp = 1000000000;
+ else {
+ mob_db[class_].job_exp = mob_db[class_].job_exp * battle_config.job_exp_rate / 100;
+ if (mob_db[class_].job_exp < 1)
+ mob_db[class_].job_exp = 1;
+ }
+
+ mob_db[class_].range=atoi(str[8]);
+ mob_db[class_].atk1=atoi(str[9]);
+ mob_db[class_].atk2=atoi(str[10]);
+ mob_db[class_].def=atoi(str[11]);
+ mob_db[class_].mdef=atoi(str[12]);
+ mob_db[class_].str=atoi(str[13]);
+ mob_db[class_].agi=atoi(str[14]);
+ mob_db[class_].vit=atoi(str[15]);
+ mob_db[class_].int_=atoi(str[16]);
+ mob_db[class_].dex=atoi(str[17]);
+ mob_db[class_].luk=atoi(str[18]);
+ mob_db[class_].range2=atoi(str[19]);
+ mob_db[class_].range3=atoi(str[20]);
+ mob_db[class_].size=atoi(str[21]);
+ mob_db[class_].race=atoi(str[22]);
+ mob_db[class_].element=atoi(str[23]);
+ mob_db[class_].mode=atoi(str[24]);
+ mob_db[class_].speed=atoi(str[25]);
+ mob_db[class_].adelay=atoi(str[26]);
+ mob_db[class_].amotion=atoi(str[27]);
+ mob_db[class_].dmotion=atoi(str[28]);
+
+ for(i=0;i<10;i++){ // 8 -> 10 Lupus
int rate = 0,type,ratemin,ratemax;
- mob_db[class].dropitem[i].nameid=atoi(str[29+i*2]);
- type = itemdb_type(mob_db[class].dropitem[i].nameid);
+ mob_db[class_].dropitem[i].nameid=atoi(str[29+i*2]);
+ type = itemdb_type(mob_db[class_].dropitem[i].nameid);
if (type == 0) { // Added by Valaris
- rate = battle_config.item_rate_heal;
+ rate = battle_config.item_rate_heal * atoi(str[30+i*2]) / 100;
ratemin = battle_config.item_drop_heal_min;
ratemax = battle_config.item_drop_heal_max;
}
else if (type == 2) {
- rate = battle_config.item_rate_use;
+ rate = battle_config.item_rate_use * atoi(str[30+i*2]) / 100;
ratemin = battle_config.item_drop_use_min;
ratemax = battle_config.item_drop_use_max; // End
}
else if (type == 4 || type == 5 || type == 8) { // Changed to include Pet Equip
- rate = battle_config.item_rate_equip;
+ rate = battle_config.item_rate_equip * atoi(str[30+i*2]) / 100;
ratemin = battle_config.item_drop_equip_min;
ratemax = battle_config.item_drop_equip_max;
}
else if (type == 6) {
- rate = battle_config.item_rate_card;
+ rate = battle_config.item_rate_card * atoi(str[30+i*2]) / 100;
ratemin = battle_config.item_drop_card_min;
ratemax = battle_config.item_drop_card_max;
}
else {
- rate = battle_config.item_rate_common;
+ rate = battle_config.item_rate_common * atoi(str[30+i*2]) / 100;
ratemin = battle_config.item_drop_common_min;
ratemax = battle_config.item_drop_common_max;
}
- rate = (rate / 100) * atoi(str[30+i*2]);
- rate = (rate < ratemin)? ratemin: (rate > ratemax)? ratemax: rate;
- mob_db[class].dropitem[i].p = rate;
+
+ mob_db[class_].dropitem[i].p = (rate < ratemin) ? ratemin : (rate > ratemax) ? ratemax: rate;
}
-
- mob_db[class].mexp=atoi(str[45])*battle_config.mvp_exp_rate/100;
- mob_db[class].mexpper=atoi(str[46]);
+ // MVP EXP Bonus, Chance: MEXP,ExpPer
+ mob_db[class_].mexp=atoi(str[49])*battle_config.mvp_exp_rate/100;
+ mob_db[class_].mexpper=atoi(str[50]);
+ // MVP Drops: MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per
for(i=0;i<3;i++){
- mob_db[class].mvpitem[i].nameid=atoi(str[47+i*2]);
- mob_db[class].mvpitem[i].p=atoi(str[48+i*2])*battle_config.mvp_item_rate/100;
+ mob_db[class_].mvpitem[i].nameid=atoi(str[51+i*2]);
+ mob_db[class_].mvpitem[i].p=atoi(str[52+i*2])*battle_config.mvp_item_rate/100;
}
for(i=0;i<MAX_RANDOMMONSTER;i++)
- mob_db[class].summonper[i]=0;
- mob_db[class].maxskill=0;
-
- mob_db[class].sex=0;
- mob_db[class].hair=0;
- mob_db[class].hair_color=0;
- mob_db[class].weapon=0;
- mob_db[class].shield=0;
- mob_db[class].head_top=0;
- mob_db[class].head_mid=0;
- mob_db[class].head_buttom=0;
+ mob_db[class_].summonper[i]=0;
+ mob_db[class_].maxskill=0;
+
+ mob_db[class_].sex=0;
+ mob_db[class_].hair=0;
+ mob_db[class_].hair_color=0;
+ mob_db[class_].weapon=0;
+ mob_db[class_].shield=0;
+ mob_db[class_].head_top=0;
+ mob_db[class_].head_mid=0;
+ mob_db[class_].head_buttom=0;
}
mysql_free_result(sql_res);
- printf("read %s done (count=%d)\n",mob_db_db,ln);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,mob_db_db);
+ ShowStatus(tmp_output);
}
return 0;
}
-
#endif /* not TXT_ONLY */
+
+void mob_reload(void)
+{
+#ifndef TXT_ONLY
+ if(db_use_sqldbs)
+ mob_read_sqldb();
+ else
+#endif /* TXT_ONLY */
+ mob_readdb();
+
+ mob_readdb_mobavail();
+ mob_read_randommonster();
+ mob_readskilldb();
+ mob_readdb_race();
+}
+
/*==========================================
* Circumference initialization of mob
*------------------------------------------
@@ -4319,13 +4552,14 @@ int do_init_mob(void)
#ifndef TXT_ONLY
if(db_use_sqldbs)
mob_read_sqldb();
- else
+ else
#endif /* TXT_ONLY */
mob_readdb();
mob_readdb_mobavail();
mob_read_randommonster();
mob_readskilldb();
+ mob_readdb_race();
add_timer_func_list(mob_timer,"mob_timer");
add_timer_func_list(mob_delayspawn,"mob_delayspawn");
diff --git a/src/map/mob.h b/src/map/mob.h
index e5a83be0f..6613c5b6b 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -3,6 +3,10 @@
#define _MOB_H_
#define MAX_RANDOMMONSTER 3
+#define MAX_MOB_RACE_DB 6
+#define MAX_MOB_DB 2000 /* Change this to increase the table size in your mob_db to accomodate
+ numbers more than 2000 for mobs if you want to (and know what you're doing).
+ Be sure to note that 4001 to 4047 are for advanced classes. */
struct mob_skill {
short state;
@@ -26,9 +30,10 @@ struct mob_db {
int str,agi,vit,int_,dex,luk;
int range,range2,range3;
int size,race,element,mode;
+ short race2; // celest
int speed,adelay,amotion,dmotion;
int mexp,mexpper;
- struct { int nameid,p; } dropitem[8];
+ struct { int nameid,p; } dropitem[10]; //8 -> 10 Lupus
struct { int nameid,p; } mvpitem[3];
int view_class,sex;
short hair,hair_color,weapon,shield,head_top,head_mid,head_buttom,option,clothes_color; // [Valaris]
@@ -72,32 +77,35 @@ enum {
};
enum {
- MSS_IDLE, // ‘Ò‹@
- MSS_WALK, // ˆÚ“®
- MSS_ATTACK, // UŒ‚
- MSS_DEAD, // Ž€–S
- MSS_LOOT, // ƒ‹[ƒg
- MSS_CHASE, // “ËŒ‚
+ MSS_IDLE, // ?@
+ MSS_WALK, // ?
+ MSS_ATTACK, // U
+ MSS_DEAD, // S
+ MSS_LOOT, // [g
+ MSS_CHASE, // ?
};
int mobdb_searchname(const char *str);
int mobdb_checkid(const int id);
int mob_once_spawn(struct map_session_data *sd,char *mapname,
- int x,int y,const char *mobname,int class,int amount,const char *event);
+ int x,int y,const char *mobname,int class_,int amount,const char *event);
int mob_once_spawn_area(struct map_session_data *sd,char *mapname,
int x0,int y0,int x1,int y1,
- const char *mobname,int class,int amount,const char *event);
+ const char *mobname,int class_,int amount,const char *event);
int mob_spawn_guardian(struct map_session_data *sd,char *mapname, // Spawning Guardians [Valaris]
- int x,int y,const char *mobname,int class,int amount,const char *event,int guardian); // Spawning Guardians [Valaris]
+ int x,int y,const char *mobname,int class_,int amount,const char *event,int guardian); // Spawning Guardians [Valaris]
int mob_walktoxy(struct mob_data *md,int x,int y,int easy);
+//int mob_randomwalk(struct mob_data *md,int tick);
+//int mob_can_move(struct mob_data *md);
int mob_target(struct mob_data *md,struct block_list *bl,int dist);
int mob_stop_walking(struct mob_data *md,int type);
int mob_stopattack(struct mob_data *);
int mob_spawn(int);
+int mob_setdelayspawn(int);
int mob_damage(struct block_list *,struct mob_data*,int,int);
int mob_changestate(struct mob_data *md,int state,int type);
int mob_heal(struct mob_data*,int);
@@ -116,8 +124,9 @@ short mob_get_clothes_color(int); //player mob dye [Valaris]
int mob_get_equip(int); // mob equip [Valaris]
int do_init_mob(void);
+void mob_unload(struct mob_data *md);
+int mob_remove_map(struct mob_data *md, int type);
int mob_delete(struct mob_data *md);
-int mob_catch_delete(struct mob_data *md,int type);
int mob_timer_delete(int tid, unsigned int tick, int id, int data);
int mob_deleteslave(struct mob_data *md);
@@ -132,6 +141,7 @@ int mobskill_event(struct mob_data *md,int flag);
int mobskill_castend_id( int tid, unsigned int tick, int id,int data );
int mobskill_castend_pos( int tid, unsigned int tick, int id,int data );
int mob_summonslave(struct mob_data *md2,int *value,int amount,int flag);
+int mob_countslave(struct mob_data *md);
int mob_gvmobcheck(struct map_session_data *sd, struct block_list *bl);
void mob_reload(void);
diff --git a/src/map/npc.c b/src/map/npc.c
index b1f9c54ec..069597f83 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -15,29 +15,39 @@
#include "clif.h"
#include "intif.h"
#include "pc.h"
+#include "status.h"
#include "itemdb.h"
#include "script.h"
#include "mob.h"
#include "pet.h"
#include "battle.h"
#include "skill.h"
+#include "grfio.h"
+#include "showmsg.h"
#ifdef MEMWATCH
#include "memwatch.h"
#endif
-
+#ifdef _WIN32
+#undef isspace
+#define isspace(x) (x == ' ' || x == '\t')
+#endif
struct npc_src_list {
struct npc_src_list * next;
- struct npc_src_list * prev;
+// struct npc_src_list * prev; //[Shinomori]
char name[4];
-} ;
+};
-static struct npc_src_list *npc_src_first,*npc_src_last;
+static struct npc_src_list *npc_src_first=NULL;
+static struct npc_src_list *npc_src_last=NULL;
static int npc_id=START_NPC_NUM;
-static int npc_warp,npc_shop,npc_script,npc_mob;
-
+static int npc_warp=0;
+static int npc_shop=0;
+static int npc_script=0;
+static int npc_mob=0;
+char *current_file = NULL;
int npc_get_new_npc_id(void){ return npc_id++; }
static struct dbt *ev_db;
@@ -62,31 +72,33 @@ int npc_enable_sub( struct block_list *bl, va_list ap )
{
struct map_session_data *sd;
struct npc_data *nd;
- char *name=(char *)aCalloc(50,sizeof(char));
+ //char *name=(char *)aCallocA(50,sizeof(char)); // fixed [Shinomori]
nullpo_retr(0, bl);
nullpo_retr(0, ap);
nullpo_retr(0, nd=va_arg(ap,struct npc_data *));
if(bl->type == BL_PC && (sd=(struct map_session_data *)bl)){
+ char name[50]; // need 24 + 9 for the "::OnTouch"
if (nd->flag&1) // –³Œø‰»‚³‚ê‚Ä‚¢‚é
return 1;
- memcpy(name,nd->name,50);
if(sd->areanpc_id==nd->bl.id)
return 1;
sd->areanpc_id=nd->bl.id;
- npc_event(sd,strcat(name,"::OnTouch"),0);
+
+ sprintf(name,"%s::OnTouch", nd->name);
+ npc_event(sd,name,0);
}
- free(name);
+ //aFree(name);
return 0;
}
int npc_enable(const char *name,int flag)
{
- struct npc_data *nd=strdb_search(npcname_db,name);
+ struct npc_data *nd= (struct npc_data *) strdb_search(npcname_db,name);
if (nd==NULL)
return 0;
-
+
if (flag&1) { // —LŒø‰»
nd->flag&=~1;
clif_spawnnpc(nd);
@@ -114,8 +126,17 @@ int npc_enable(const char *name,int flag)
*/
struct npc_data* npc_name2id(const char *name)
{
- return strdb_search(npcname_db,name);
+ return (struct npc_data *) strdb_search(npcname_db,name);
+}
+
+void ev_release(struct dbn *db, int which)
+{
+ if (which & 0x1)
+ aFree(db->key);
+ if (which & 0x2)
+ aFree(db->data);
}
+
/*==========================================
* ƒCƒxƒ“ƒgƒLƒ…[‚̃Cƒxƒ“ƒgˆ—
*------------------------------------------
@@ -126,47 +147,69 @@ int npc_event_dequeue(struct map_session_data *sd)
sd->npc_id=0;
if (sd->eventqueue[0][0]) { // ƒLƒ…[‚̃Cƒxƒ“ƒgˆ—
- char *name=(char *)aCalloc(50,sizeof(char));
- int i;
+ size_t ev;
- memcpy(name,sd->eventqueue[0],50);
- for(i=MAX_EVENTQUEUE-2;i>=0;i--)
- memcpy(sd->eventqueue[i],sd->eventqueue[i+1],50);
- add_timer(gettick()+100,npc_event_timer,sd->bl.id,(int)name);
+ // find an empty place in eventtimer list
+ for(ev=0;ev<MAX_EVENTTIMER;ev++)
+ if( sd->eventtimer[ev]==-1 )
+ break;
+ if(ev<MAX_EVENTTIMER)
+ { // generate and insert the timer
+ int i;
+ // copy the first event name
+ char *name=(char *)aMalloc(50*sizeof(char));
+ memcpy(name,sd->eventqueue[0],50);
+ // shift queued events down by one
+ for(i=1;i<MAX_EVENTQUEUE;i++)
+ memcpy(sd->eventqueue[i-1],sd->eventqueue[i],50);
+ // clear the last event
+ sd->eventqueue[MAX_EVENTQUEUE-1][0]=0;
+ // add the timer
+ sd->eventtimer[ev]=add_timer(gettick()+100,pc_eventtimer,sd->bl.id,(int)name);//!!todo!!
+
+ }else
+ printf("npc_event_dequeue: event timer is full !\n");
}
return 0;
}
-int npc_delete(struct npc_data *nd)
-{
- nullpo_retr(1, nd);
-
- if(nd->bl.prev == NULL)
- return 1;
-
- clif_clearchar_area(&nd->bl,1);
- map_delblock(&nd->bl);
- return 0;
-}
-
/*==========================================
* ƒCƒxƒ“ƒg‚Ì’x‰„ŽÀs
*------------------------------------------
*/
int npc_event_timer(int tid,unsigned int tick,int id,int data)
{
+ char *eventname = (char *)data;
+ struct event_data *ev = (struct event_data *)strdb_search(ev_db,eventname);
+ struct npc_data *nd;
struct map_session_data *sd=map_id2sd(id);
- if (sd==NULL)
- return 0;
-
- npc_event(sd,(const char *)data,0);
- free((void*)data);
+ size_t i;
+
+ if((ev==NULL || (nd=ev->nd)==NULL))
+ {
+ if(battle_config.error_log)
+ printf("npc_event: event not found [%s]\n",eventname);
+ }
+ else
+ {
+ for(i=0;i<MAX_EVENTTIMER;i++) {
+ if( nd->eventtimer[i]==tid ) {
+ nd->eventtimer[i]=-1;
+ npc_event(sd,eventname,0); // sd NULL check is within
+ break;
+ }
+ }
+ if(i==MAX_EVENTTIMER && battle_config.error_log)
+ printf("npc_event_timer: event timer not found [%s]!\n",eventname);
+ }
+
+ aFree(eventname);
return 0;
}
int npc_timer_event(const char *eventname) // Added by RoVeRT
{
- struct event_data *ev=strdb_search(ev_db,eventname);
+ struct event_data *ev=(struct event_data *) strdb_search(ev_db,eventname);
struct npc_data *nd;
// int xs,ys;
@@ -220,7 +263,7 @@ int npc_timer(int tid,unsigned int tick,int id,int data) // Added by RoVeRT
{
strdb_foreach(npcname_db,npc_timer_sub);
- free((void*)data);
+ aFree((void*)data);
return 0;
}*/
/*==========================================
@@ -233,14 +276,14 @@ int npc_event_export(void *key,void *data,va_list ap)
char *lname=(char *)key;
int pos=(int)data;
struct npc_data *nd=va_arg(ap,struct npc_data *);
-
+
if ((lname[0]=='O' || lname[0]=='o')&&(lname[1]=='N' || lname[1]=='n')) {
struct event_data *ev;
char *buf;
char *p=strchr(lname,':');
// ƒGƒNƒXƒ|[ƒg‚³‚ê‚é
- ev=calloc(sizeof(struct event_data), 1);
- buf=calloc(50, 1);
+ ev=(struct event_data *) aCalloc(sizeof(struct event_data), 1);
+ buf=(char *) aCallocA(50, 1);
if (ev==NULL || buf==NULL) {
printf("npc_event_export: out of memory !\n");
exit(1);
@@ -261,62 +304,6 @@ int npc_event_export(void *key,void *data,va_list ap)
return 0;
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/*==========================================
* ‘S‚Ä‚ÌNPC‚ÌOn*ƒCƒxƒ“ƒgŽÀs
*------------------------------------------
@@ -326,29 +313,39 @@ int npc_event_doall_sub(void *key,void *data,va_list ap)
char *p=(char *)key;
struct event_data *ev;
int *c;
+ int rid;
const char *name;
nullpo_retr(0, ev=(struct event_data *)data);
nullpo_retr(0, ap);
nullpo_retr(0, c=va_arg(ap,int *));
-
name=va_arg(ap,const char *);
+ rid=va_arg(ap, int);
if( (p=strchr(p,':')) && p && strcmpi(name,p)==0 ){
- run_script(ev->nd->u.scr.script,ev->pos,0,ev->nd->bl.id);
+ run_script(ev->nd->u.scr.script,ev->pos,rid,ev->nd->bl.id);
(*c)++;
}
-
+
return 0;
}
int npc_event_doall(const char *name)
{
int c=0;
char buf[64]="::";
-
+
+ strncpy(buf+2,name,62);
+ strdb_foreach(ev_db,npc_event_doall_sub,&c,buf,0);
+ return c;
+}
+int npc_event_doall_id(const char *name, int rid)
+{
+ int c=0;
+ char buf[64]="::";
+
strncpy(buf+2,name,62);
- strdb_foreach(ev_db,npc_event_doall_sub,&c,buf);
- return c;
+ strdb_foreach(ev_db,npc_event_doall_sub,&c,buf,rid);
+ return c;
}
int npc_event_do_sub(void *key,void *data,va_list ap)
@@ -374,7 +371,7 @@ int npc_event_do_sub(void *key,void *data,va_list ap)
int npc_event_do(const char *name)
{
int c=0;
-
+
if (*name==':' && name[1]==':') {
return npc_event_doall(name+2);
}
@@ -394,7 +391,7 @@ int npc_event_do_clock(int tid,unsigned int tick,int id,int data)
char buf[64];
char *day="";
int c=0;
-
+
time(&timer);
t=localtime(&timer);
@@ -407,7 +404,7 @@ int npc_event_do_clock(int tid,unsigned int tick,int id,int data)
case 5: day = "Fri"; break;
case 6: day = "Sat"; break;
}
-
+
if (t->tm_min != ev_tm_b.tm_min ) {
sprintf(buf,"OnMinute%02d",t->tm_min);
c+=npc_event_doall(buf);
@@ -433,8 +430,10 @@ int npc_event_do_clock(int tid,unsigned int tick,int id,int data)
*/
int npc_event_do_oninit(void)
{
- int c = npc_event_doall("OnInit");
- printf("npc: OnInit Event done. (%d npc)\n",c);
+// int c = npc_event_doall("OnInit");
+ sprintf(tmp_output,"Event '"CL_WHITE"OnInit"CL_RESET"' executed with '"
+ CL_WHITE"%d"CL_RESET"' NPCs.\n",npc_event_doall("OnInit"));
+ ShowStatus(tmp_output);
add_timer_interval(gettick()+100,
npc_event_do_clock,0,0,1000);
@@ -452,7 +451,7 @@ int npc_addeventtimer(struct npc_data *nd,int tick,const char *name)
if( nd->eventtimer[i]==-1 )
break;
if(i<MAX_EVENTTIMER){
- char *evname=malloc(24);
+ char *evname=(char *) aMallocA(24);
if(evname==NULL){
printf("npc_addeventtimer: out of memory !\n");exit(1);
}
@@ -493,33 +492,33 @@ int npc_cleareventtimer(struct npc_data *nd)
int npc_do_ontimer_sub(void *key,void *data,va_list ap)
{
- char *p=(char *)key;
- struct event_data *ev=(struct event_data *)data;
- int *c=va_arg(ap,int *);
+ char *p = (char *)key;
+ struct event_data *ev = (struct event_data *)data;
+ int *c = va_arg(ap,int *);
// struct map_session_data *sd=va_arg(ap,struct map_session_data *);
- int option=va_arg(ap,int);
- int tick=0;
+ int option = va_arg(ap,int);
+ int tick = 0;
char temp[10];
char event[50];
- if(ev->nd->bl.id==(int)*c && (p=strchr(p,':')) && p && strnicmp("::OnTimer",p,8)==0 ){
- sscanf(&p[9],"%s",temp);
- tick=atoi(temp);
+ if(ev->nd->bl.id == (int)*c && (p = strchr(p,':')) && strnicmp("::OnTimer",p,8) == 0){
+ sscanf(&p[9], "%s", temp);
+ tick = atoi(temp);
- strcpy( event, ev->nd->name);
- strcat( event, p);
+ strcpy(event, ev->nd->name);
+ strcat(event, p);
if (option!=0) {
- npc_addeventtimer(ev->nd,tick,event);
+ npc_addeventtimer(ev->nd, tick, event);
} else {
- npc_deleventtimer(ev->nd,event);
+ npc_deleventtimer(ev->nd, event);
}
}
return 0;
}
-int npc_do_ontimer(int npc_id, struct map_session_data *sd, int option)
+int npc_do_ontimer(int npc_id, int option)
{
- strdb_foreach(ev_db,npc_do_ontimer_sub,&npc_id,sd,option);
+ strdb_foreach(ev_db, npc_do_ontimer_sub, &npc_id, option);
return 0;
}
/*==========================================
@@ -533,13 +532,13 @@ int npc_timerevent_import(void *key,void *data,va_list ap)
int pos=(int)data;
struct npc_data *nd=va_arg(ap,struct npc_data *);
int t=0,i=0;
-
+
if(sscanf(lname,"OnTimer%d%n",&t,&i)==1 && lname[i]==':') {
// ƒ^ƒCƒ}[ƒCƒxƒ“ƒg
struct npc_timerevent_list *te=nd->u.scr.timer_event;
int j,i=nd->u.scr.timeramount;
- if(te==NULL) te=malloc(sizeof(struct npc_timerevent_list));
- else te=realloc( te, sizeof(struct npc_timerevent_list) * (i+1) );
+ if(te==NULL) te=(struct npc_timerevent_list*)aMallocA(sizeof(struct npc_timerevent_list));
+ else te= (struct npc_timerevent_list*)aRealloc( te, sizeof(struct npc_timerevent_list) * (i+1) );
if(te==NULL){
printf("npc_timerevent_import: out of memory !\n");
exit(1);
@@ -573,7 +572,7 @@ int npc_timerevent(int tid,unsigned int tick,int id,int data)
nd->u.scr.timertick=tick;
te=nd->u.scr.timer_event+ nd->u.scr.nexttimer;
nd->u.scr.timerid = -1;
-
+
t = nd->u.scr.timer+=data;
nd->u.scr.nexttimer++;
if( nd->u.scr.timeramount>nd->u.scr.nexttimer ){
@@ -581,14 +580,14 @@ int npc_timerevent(int tid,unsigned int tick,int id,int data)
nd->u.scr.timerid = add_timer(tick+next,npc_timerevent,id,next);
}
- run_script(nd->u.scr.script,te->pos,0,nd->bl.id);
+ run_script(nd->u.scr.script,te->pos,nd->u.scr.rid,nd->bl.id);
return 0;
}
/*==========================================
* ƒ^ƒCƒ}[ƒCƒxƒ“ƒgŠJŽn
*------------------------------------------
*/
-int npc_timerevent_start(struct npc_data *nd)
+int npc_timerevent_start(struct npc_data *nd, int rid)
{
int j,n, next;
@@ -597,17 +596,19 @@ int npc_timerevent_start(struct npc_data *nd)
n=nd->u.scr.timeramount;
if( nd->u.scr.nexttimer>=0 || n==0 )
return 0;
-
+
for(j=0;j<n;j++){
if( nd->u.scr.timer_event[j].timer > nd->u.scr.timer )
break;
}
+ if(j>=n) // check if there is a timer to use !!BEFORE!! you write stuff to the structures [Shinomori]
+ return 0;
+
nd->u.scr.nexttimer=j;
nd->u.scr.timertick=gettick();
+ if (rid >= 0) nd->u.scr.rid=rid; // changed to: attaching to given rid by default [Shinomori]
+ // if rid is less than 0 leave it unchanged [celest]
- if(j>=n)
- return 0;
-
next = nd->u.scr.timer_event[j].timer - nd->u.scr.timer;
nd->u.scr.timerid = add_timer(gettick()+next,npc_timerevent,nd->bl.id,next);
return 0;
@@ -626,6 +627,7 @@ int npc_timerevent_stop(struct npc_data *nd)
if(nd->u.scr.timerid!=-1)
delete_timer(nd->u.scr.timerid,npc_timerevent);
nd->u.scr.timerid = -1;
+ nd->u.scr.rid = 0;
}
return 0;
}
@@ -660,7 +662,7 @@ int npc_settimerevent_tick(struct npc_data *nd,int newtimer)
npc_timerevent_stop(nd);
nd->u.scr.timer=newtimer;
if(flag>=0)
- npc_timerevent_start(nd);
+ npc_timerevent_start(nd, -1);
return 0;
}
@@ -670,7 +672,7 @@ int npc_settimerevent_tick(struct npc_data *nd,int newtimer)
*/
int npc_event(struct map_session_data *sd,const char *eventname,int mob_kill)
{
- struct event_data *ev=strdb_search(ev_db,eventname);
+ struct event_data *ev=(struct event_data *) strdb_search(ev_db,eventname);
struct npc_data *nd;
int xs,ys;
char mobevent[100];
@@ -686,7 +688,7 @@ int npc_event(struct map_session_data *sd,const char *eventname,int mob_kill)
if(mob_kill && (ev==NULL || (nd=ev->nd)==NULL)){
strcpy( mobevent, eventname);
strcat( mobevent, "::OnMyMobDead");
- ev=strdb_search(ev_db,mobevent);
+ ev= (struct event_data *) strdb_search(ev_db,mobevent);
if (ev==NULL || (nd=ev->nd)==NULL) {
if (strnicmp(eventname,"GM_MONSTER",10)!=0)
printf("npc_event: event not found [%s]\n",mobevent);
@@ -732,7 +734,7 @@ int npc_event(struct map_session_data *sd,const char *eventname,int mob_kill)
npc_event_dequeue(sd);
return 0;
}
-
+
sd->npc_id=nd->bl.id;
sd->npc_pos=run_script(nd->u.scr.script,ev->pos,sd->bl.id,nd->bl.id);
return 0;
@@ -753,7 +755,7 @@ int npc_command_sub(void *key,void *data,va_list ap)
if (strcmp(command,temp)==0)
run_script(ev->nd->u.scr.script,ev->pos,0,ev->nd->bl.id);
}
-
+
return 0;
}
@@ -782,7 +784,7 @@ int npc_touch_areanpc(struct map_session_data *sd,int m,int x,int y)
f=0;
continue;
}
-
+
switch(map[m].npc[i]->bl.subtype) {
case WARP:
xs=map[m].npc[i]->u.warp.xs;
@@ -813,15 +815,18 @@ int npc_touch_areanpc(struct map_session_data *sd,int m,int x,int y)
break;
case SCRIPT:
{
- char *name=(char *)aCalloc(50,sizeof(char));
+ //char *name=(char *)aCallocA(50,sizeof(char)); // fixed [Shinomori]
+ char name[50]; // need 24 max + 9 for "::OnTouch"
- memcpy(name,map[m].npc[i]->name,50);
- if(sd->areanpc_id==map[m].npc[i]->bl.id)
+ if(sd->areanpc_id == map[m].npc[i]->bl.id)
return 1;
- sd->areanpc_id=map[m].npc[i]->bl.id;
- if(npc_event(sd,strcat(name,"::OnTouch"),0)>0)
+ sd->areanpc_id = map[m].npc[i]->bl.id;
+
+ sprintf(name,"%s::OnTouch", map[m].npc[i]->name);
+
+ if( npc_event(sd,name,0)>0 )
npc_click(sd,map[m].npc[i]->bl.id);
- free(name);
+ //aFree(name);
break;
}
}
@@ -844,8 +849,8 @@ int npc_checknear(struct map_session_data *sd,int id)
printf("no such npc : %d\n",id);
return 1;
}
-
- if (nd->class<0) // ƒCƒxƒ“ƒgŒn‚Íí‚ÉOK
+
+ if (nd->class_<0) // ƒCƒxƒ“ƒgŒn‚Íí‚ÉOK
return 0;
// ƒGƒŠƒA”»’è
@@ -858,6 +863,32 @@ int npc_checknear(struct map_session_data *sd,int id)
}
/*==========================================
+ * NPC‚̃I[ƒvƒ“ƒ`ƒƒƒbƒg”­Œ¾
+ *------------------------------------------
+ */
+int npc_globalmessage(const char *name,char *mes)
+{
+ struct npc_data *nd=(struct npc_data *) strdb_search(npcname_db,name);
+ char temp[100];
+ char ntemp[50];
+ char *ltemp;
+
+ if(nd==NULL) return 0;
+ if(name==NULL) return 0;
+
+ ltemp=strchr(name,'#');
+ if(ltemp!=NULL) {
+ strncpy(ntemp,name,ltemp - name); // 123#456 ‚Ì # ‚©‚çŒã‚ë‚ð휂·‚é
+ ntemp[ltemp - name]=0x00; // strncpy ‚̃oƒOHŽg‚¢•ûŠÔˆá‚Á‚Ä‚éH
+ }
+
+ snprintf(temp, sizeof temp ,"%s : %s",ntemp,mes);
+ clif_GlobalMessage(&nd->bl,temp);
+
+ return 0;
+}
+
+/*==========================================
* ƒNƒŠƒbƒNŽž‚ÌNPCˆ—
*------------------------------------------
*/
@@ -957,7 +988,7 @@ int npc_buylist(struct map_session_data *sd,int n,unsigned short *item_list)
{
struct npc_data *nd;
double z;
- int i,j,w,skill,itemamount=0,new=0;
+ int i,j,w,skill,itemamount=0,new_=0;
nullpo_retr(3, sd);
nullpo_retr(3, item_list);
@@ -987,7 +1018,7 @@ int npc_buylist(struct map_session_data *sd,int n,unsigned short *item_list)
case ADDITEM_EXIST:
break;
case ADDITEM_NEW:
- new++;
+ new_++;
break;
case ADDITEM_OVERAMOUNT:
return 2;
@@ -999,7 +1030,7 @@ int npc_buylist(struct map_session_data *sd,int n,unsigned short *item_list)
return 1; // zeny•s‘«
if (w+sd->weight > sd->max_weight)
return 2; // d—Ê’´‰ß
- if (pc_inventoryblank(sd)<new)
+ if (pc_inventoryblank(sd)<new_)
return 3; // Ží—Þ”’´‰ß
pc_payzeny(sd,(int)z);
@@ -1014,7 +1045,7 @@ int npc_buylist(struct map_session_data *sd,int n,unsigned short *item_list)
}
//¤lŒoŒ±’l
-/* if ((sd->status.class == 5) || (sd->status.class == 10) || (sd->status.class == 18)) {
+/* if ((sd->status.class_ == 5) || (sd->status.class_ == 10) || (sd->status.class_ == 18)) {
z = z * pc_checkskill(sd,MC_DISCOUNT) / ((1 + 300 / itemamount) * 4000) * battle_config.shop_exp;
pc_gainexp(sd,0,z);
}*/
@@ -1022,7 +1053,7 @@ int npc_buylist(struct map_session_data *sd,int n,unsigned short *item_list)
if (sd->status.skill[MC_DISCOUNT].flag != 0)
skill = sd->status.skill[MC_DISCOUNT].flag - 2;
if (skill > 0) {
- z = (log(z * (double)skill) * (double)battle_config.shop_exp/100.);
+ z = z * (double)skill * (double)battle_config.shop_exp/10000.;
if (z < 1)
z = 1;
pc_gainexp(sd,0,(int)z);
@@ -1074,7 +1105,7 @@ int npc_selllist(struct map_session_data *sd,int n,unsigned short *item_list)
}
//¤lŒoŒ±’l
-/* if ((sd->status.class == 5) || (sd->status.class == 10) || (sd->status.class == 18)) {
+/* if ((sd->status.class_ == 5) || (sd->status.class_ == 10) || (sd->status.class_ == 18)) {
z = z * pc_checkskill(sd,MC_OVERCHARGE) / ((1 + 500 / itemamount) * 4000) * battle_config.shop_exp ;
pc_gainexp(sd,0,z);
}*/
@@ -1082,7 +1113,7 @@ int npc_selllist(struct map_session_data *sd,int n,unsigned short *item_list)
if (sd->status.skill[MC_OVERCHARGE].flag != 0)
skill = sd->status.skill[MC_OVERCHARGE].flag - 2;
if (skill > 0) {
- z = (log(z * (double)skill) * (double)battle_config.shop_exp/100.);
+ z = z * (double)skill * (double)battle_config.shop_exp/10000.;
if (z < 1)
z = 1;
pc_gainexp(sd,0,(int)z);
@@ -1106,8 +1137,8 @@ static int calc_next_walk_step(struct npc_data *nd)
if(nd->walkpath.path_pos>=nd->walkpath.path_len)
return -1;
if(nd->walkpath.path[nd->walkpath.path_pos]&1)
- return battle_get_speed(&nd->bl)*14/10;
- return battle_get_speed(&nd->bl);
+ return status_get_speed(&nd->bl)*14/10;
+ return status_get_speed(&nd->bl);
}
@@ -1118,7 +1149,7 @@ static int calc_next_walk_step(struct npc_data *nd)
static int npc_walk(struct npc_data *nd,unsigned int tick,int data)
{
int moveblock;
- int i,ctype;
+ int i;
static int dirx[8]={0,-1,-1,-1,0,1,1,1};
static int diry[8]={1,1,0,-1,-1,-1,0,1};
int x,y,dx,dy;
@@ -1143,8 +1174,7 @@ static int npc_walk(struct npc_data *nd,unsigned int tick,int data)
x = nd->bl.x;
y = nd->bl.y;
- ctype = map_getcell(nd->bl.m,x,y);
- if(ctype == 1 || ctype == 5) {
+ if(map_getcell(nd->bl.m,x,y,CELL_CHKNOPASS)) {
npc_stop_walking(nd,1);
return 0;
}
@@ -1152,8 +1182,7 @@ static int npc_walk(struct npc_data *nd,unsigned int tick,int data)
dx = dirx[nd->dir];
dy = diry[nd->dir];
- ctype = map_getcell(nd->bl.m,x+dx,y+dy);
- if(ctype == 1 || ctype == 5) {
+ if(map_getcell(nd->bl.m,x+dx,y+dy,CELL_CHKNOPASS)) {
npc_walktoxy_sub(nd);
return 0;
}
@@ -1183,7 +1212,7 @@ static int npc_walk(struct npc_data *nd,unsigned int tick,int data)
if(nd->walkpath.path_pos>=nd->walkpath.path_len)
clif_fixnpcpos(nd); // When npc stops, retransmission current of a position.
-
+
}
return 0;
}
@@ -1228,7 +1257,7 @@ static int npc_walktimer(int tid,unsigned int tick,int id,int data)
if(nd->walktimer != tid){
return 0;
}
-
+
nd->walktimer=-1;
if(nd->bl.prev == NULL)
@@ -1293,7 +1322,7 @@ int npc_stop_walking(struct npc_data *nd,int type)
if(nd->state.state == MS_WALK || nd->state.state == MS_IDLE) {
int dx=0,dy=0;
-
+
nd->walkpath.path_len=0;
if(type&4){
dx=nd->to_x-nd->bl.x;
@@ -1318,7 +1347,7 @@ int npc_stop_walking(struct npc_data *nd,int type)
if(type&0x01)
clif_fixnpcpos(nd);
if(type&0x02) {
- int delay=battle_get_dmotion(&nd->bl);
+ int delay=status_get_dmotion(&nd->bl);
unsigned int tick = gettick();
if(nd->canmove_tick < tick)
nd->canmove_tick = tick + delay;
@@ -1327,6 +1356,56 @@ int npc_stop_walking(struct npc_data *nd,int type)
return 0;
}
+int npc_remove_map (struct npc_data *nd)
+{
+ nullpo_retr(1, nd);
+
+ if(nd->bl.prev == NULL)
+ return 1;
+
+#ifdef PCRE_SUPPORT
+ npc_chat_finalize(nd);
+#endif
+ clif_clearchar_area(&nd->bl,2);
+ strdb_erase(npcname_db, nd->name);
+ map_delblock(&nd->bl);
+ map_deliddb(&nd->bl);
+
+ return 0;
+}
+
+int npc_unload(struct npc_data *nd)
+{
+ nullpo_retr (0, nd);
+
+ if (nd->chat_id) {
+ struct chat_data *cd = (struct chat_data*)map_id2bl(nd->chat_id);
+ if (cd) aFree (cd);
+ cd = NULL;
+ }
+ if (nd->bl.subtype == SCRIPT) {
+ if (nd->u.scr.timerid != -1)
+ delete_timer(nd->u.scr.timerid, npc_timerevent);
+ npc_cleareventtimer (nd);
+ if (nd->u.scr.timer_event)
+ aFree(nd->u.scr.timer_event);
+ if (nd->u.scr.src_id == 0) {
+ if(nd->u.scr.script) {
+ aFree(nd->u.scr.script);
+ nd->u.scr.script = NULL;
+ }
+ if (nd->u.scr.label_list) {
+ aFree(nd->u.scr.label_list);
+ nd->u.scr.label_list = NULL;
+ }
+ }
+ }
+ npc_remove_map (nd);
+ aFree(nd);
+ nd = NULL;
+
+ return 0;
+}
//
// ‰Šú‰»ŠÖŒW
@@ -1343,7 +1422,7 @@ void npc_clearsrcfile()
while( p ) {
struct npc_src_list *p2=p;
p=p->next;
- free(p2);
+ aFree(p2);
}
npc_src_first=NULL;
npc_src_last=NULL;
@@ -1354,7 +1433,7 @@ void npc_clearsrcfile()
*/
void npc_addsrcfile(char *name)
{
- struct npc_src_list *new;
+ struct npc_src_list *new_;
size_t len;
if ( strcmpi(name,"clear")==0 ) {
@@ -1362,16 +1441,27 @@ void npc_addsrcfile(char *name)
return;
}
- len = sizeof(*new) + strlen(name);
- new=(struct npc_src_list *)aCalloc(1,len);
- new->next = NULL;
- strncpy(new->name,name,strlen(name)+1);
+ {
+ // prevent multiple insert of source files
+ struct npc_src_list *p=npc_src_first;
+ while( p )
+ { // found the file, no need to insert it again
+ if( 0==strcmp(name,p->name) )
+ return;
+ p=p->next;
+ }
+ }
+
+ len = sizeof(*new_) + strlen(name);
+ new_=(struct npc_src_list *)aCalloc(1,len);
+ new_->next = NULL;
+ strncpy(new_->name,name,strlen(name)+1);
if (npc_src_first==NULL)
- npc_src_first = new;
+ npc_src_first = new_;
if (npc_src_last)
- npc_src_last->next = new;
+ npc_src_last->next = new_;
- npc_src_last=new;
+ npc_src_last=new_;
}
/*==========================================
* “ǂݞ‚Þnpcƒtƒ@ƒCƒ‹‚Ìíœ
@@ -1391,7 +1481,7 @@ void npc_delsrcfile(char *name)
*lp=p->next;
if ( npc_src_last==p )
npc_src_last=pp;
- free(p);
+ aFree(p);
break;
}
}
@@ -1432,9 +1522,9 @@ int npc_parse_warp(char *w1,char *w2,char *w3,char *w4)
nd->chat_id=0;
if (!battle_config.warp_point_debug)
- nd->class=WARP_CLASS;
+ nd->class_=WARP_CLASS;
else
- nd->class=WARP_DEBUG_CLASS;
+ nd->class_=WARP_DEBUG_CLASS;
nd->speed=200;
nd->option = 0;
nd->opt1 = 0;
@@ -1449,11 +1539,9 @@ int npc_parse_warp(char *w1,char *w2,char *w3,char *w4)
for(i=0;i<ys;i++) {
for(j=0;j<xs;j++) {
- int t;
- t=map_getcell(m,x-xs/2+j,y-ys/2+i);
- if (t==1 || t==5)
+ if(map_getcell(m,x-xs/2+j,y-ys/2+i,CELL_CHKNOPASS))
continue;
- map_setcell(m,x-xs/2+j,y-ys/2+i,t|0x80);
+ map_setcell(m,x-xs/2+j,y-ys/2+i,CELL_SETNPC);
}
}
@@ -1494,20 +1582,26 @@ static int npc_parse_shop(char *w1,char *w2,char *w3,char *w4)
while (p && pos < max) {
int nameid,value;
+ struct item_data *id;
p++;
if (sscanf(p, "%d:%d", &nameid, &value) != 2)
break;
nd->u.shop_item[pos].nameid = nameid;
- if (value < 0) {
- struct item_data *id = itemdb_search(nameid);
+ id = itemdb_search(nameid);
+ if (value < 0)
value = id->value_buy;
- }
nd->u.shop_item[pos].value = value;
+ // check for bad prices that can possibly cause exploits
+ if (value*75/100 < id->value_sell*124/100) {
+ sprintf (tmp_output, "Item %s [%d] buying:%d < selling:%d\n",
+ id->name, id->nameid, value*75/100, id->value_sell*124/100);
+ ShowWarning (tmp_output);
+ }
pos++;
p=strchr(p,',');
}
if (pos == 0) {
- free(nd);
+ aFree(nd);
return 1;
}
nd->u.shop_item[pos++].nameid = 0;
@@ -1520,14 +1614,14 @@ static int npc_parse_shop(char *w1,char *w2,char *w3,char *w4)
nd->dir = dir;
nd->flag = 0;
memcpy(nd->name, w3, 24);
- nd->class = atoi(w4);
+ nd->class_ = atoi(w4);
nd->speed = 200;
nd->chat_id = 0;
nd->option = 0;
nd->opt1 = 0;
nd->opt2 = 0;
nd->opt3 = 0;
-
+
nd = (struct npc_data *)aRealloc(nd,
sizeof(struct npc_data) + sizeof(nd->u.shop_item[0]) * pos);
@@ -1554,20 +1648,28 @@ int npc_convertlabel_db(void *key,void *data,va_list ap)
struct npc_label_list *lst;
int num;
char *p=strchr(lname,':');
-
+
nullpo_retr(0, ap);
nullpo_retr(0, nd=va_arg(ap,struct npc_data *));
lst=nd->u.scr.label_list;
num=nd->u.scr.label_list_num;
if(!lst){
- lst=(struct npc_label_list *)aCalloc(1,sizeof(struct npc_label_list));
+ lst=(struct npc_label_list *)aCallocA(1,sizeof(struct npc_label_list));
num=0;
}else
lst=(struct npc_label_list *)aRealloc(lst,sizeof(struct npc_label_list)*(num+1));
*p='\0';
- strncpy(lst[num].name,lname,24);
+
+ // here we check if the label fit into the buffer
+ if (strlen(lname)>23) {
+ printf("npc_parse_script: label name longer than 23 chars! '%s'\n (%s)", lname, current_file);
+ exit(1);
+ }
+ memcpy(lst[num].name,lname,strlen(lname)+1); //including EOS
+
+
*p=':';
lst[num].pos=pos;
nd->u.scr.label_list=lst;
@@ -1580,7 +1682,7 @@ int npc_convertlabel_db(void *key,void *data,va_list ap)
*/
static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line,FILE *fp,int *lines)
{
- int x,y,dir=0,m,xs=0,ys=0,class=0; // [Valaris] thanks to fov
+ int x,y,dir=0,m,xs=0,ys=0,class_=0; // [Valaris] thanks to fov
char mapname[24];
unsigned char *srcbuf=NULL,*script;
int srcsize=65536;
@@ -1609,94 +1711,92 @@ static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line
if(strcmp(w2,"script")==0){
// ƒXƒNƒŠƒvƒg‚̉ðÍ
- srcbuf=(char *)aCalloc(srcsize,sizeof(char));
+ srcbuf=(unsigned char *)aCallocA(srcsize,sizeof(char));
if (strchr(first_line,'{')) {
- strcpy(srcbuf,strchr(first_line,'{'));
+ strcpy((char *) srcbuf,strchr(first_line,'{'));
startline=*lines;
} else
srcbuf[0]=0;
while(1) {
- for(i=strlen(srcbuf)-1;i>=0 && isspace(srcbuf[i]);i--);
+ for(i=strlen((const char *) srcbuf)-1;i>=0 && isspace(srcbuf[i]);i--);
if (i>=0 && srcbuf[i]=='}')
break;
- fgets(line,1020,fp);
+ fgets((char *) line,1020,fp);
(*lines)++;
if (feof(fp))
break;
- if (strlen(srcbuf)+strlen(line)+1>=srcsize) {
+ if (strlen((char *) srcbuf)+strlen((char *) line)+1>=srcsize) {
srcsize += 65536;
- srcbuf = (char *)aRealloc(srcbuf, srcsize);
+ srcbuf = (unsigned char *)aRealloc(srcbuf, srcsize);
memset(srcbuf + srcsize - 65536, '\0', 65536);
}
if (srcbuf[0]!='{') {
- if (strchr(line,'{')) {
- strcpy(srcbuf,strchr(line,'{'));
+ if (strchr((char *) line,'{')) {
+ strcpy((char *) srcbuf,strchr((const char *) line,'{'));
startline=*lines;
}
} else
- strcat(srcbuf,line);
+ strcat((char *) srcbuf,(const char *) line);
}
- script=parse_script(srcbuf,startline);
+ script=(unsigned char *) parse_script((unsigned char *) srcbuf,startline);
if (script==NULL) {
// script parse error?
- free(srcbuf);
+ aFree(srcbuf);
return 1;
}
}else{
// duplicate‚·‚é
-
+
char srcname[128];
struct npc_data *nd2;
if( sscanf(w2,"duplicate(%[^)])",srcname)!=1 ){
- printf("bad duplicate name! : %s",w2);
+ printf("bad duplicate name (in %s)! : %s",current_file, w2);
return 0;
}
if( (nd2=npc_name2id(srcname))==NULL ){
- printf("bad duplicate name! (not exist) : %s\n",srcname);
+ printf("bad duplicate name (in %s)! (not exist) : %s\n", current_file, srcname);
return 0;
}
- script=nd2->u.scr.script;
+ script=(unsigned char *)nd2->u.scr.script;
label_dup=nd2->u.scr.label_list;
label_dupnum=nd2->u.scr.label_list_num;
src_id=nd2->bl.id;
-
+
}// end of ƒXƒNƒŠƒvƒg‰ðÍ
nd=(struct npc_data *)aCalloc(1,sizeof(struct npc_data));
if(m==-1){
// ƒXƒNƒŠƒvƒgƒRƒs[—p‚̃_ƒ~[NPC
-
- }else if( sscanf(w4,"%d,%d,%d",&class,&xs,&ys)==3) {
+
+ }else if( sscanf(w4,"%d,%d,%d",&class_,&xs,&ys)==3) {
// ÚGŒ^NPC
int i,j;
-
+
if (xs>=0)xs=xs*2+1;
if (ys>=0)ys=ys*2+1;
-
- if (class>=0) {
+
+ if (class_>=0) {
for(i=0;i<ys;i++) {
for(j=0;j<xs;j++) {
- int t;
- t=map_getcell(m,x-xs/2+j,y-ys/2+i);
- if (t==1 || t==5)
+ if(map_getcell(m,x-xs/2+j,y-ys/2+i,CELL_CHKNOPASS))
continue;
- map_setcell(m,x-xs/2+j,y-ys/2+i,t|0x80);
+ map_setcell(m,x-xs/2+j,y-ys/2+i,CELL_SETNPC);
}
}
}
-
+
nd->u.scr.xs=xs;
nd->u.scr.ys=ys;
} else { // ƒNƒŠƒbƒNŒ^NPC
- class=atoi(w4);
+ class_=atoi(w4);
nd->u.scr.xs=0;
nd->u.scr.ys=0;
}
-
- if (class<0 && m>=0) { // ƒCƒxƒ“ƒgŒ^NPC
+
+ if (class_<0 && m>=0) { // ƒCƒxƒ“ƒgŒ^NPC
evflag=1;
}
@@ -1719,9 +1819,9 @@ static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line
nd->bl.id=npc_get_new_npc_id();
nd->dir = dir;
nd->flag=0;
- nd->class=class;
+ nd->class_=class_;
nd->speed=200;
- nd->u.scr.script=script;
+ nd->u.scr.script=(char *) script;
nd->u.scr.src_id=src_id;
nd->chat_id=0;
nd->option = 0;
@@ -1730,7 +1830,7 @@ static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line
nd->opt3 = 0;
nd->walktimer=-1;
- //printf("script npc %s %d %d read done\n",mapname,nd->bl.id,nd->class);
+ //printf("script npc %s %d %d read done\n",mapname,nd->bl.id,nd->class_);
npc_script++;
nd->bl.type=BL_NPC;
nd->bl.subtype=SCRIPT;
@@ -1738,6 +1838,11 @@ static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line
nd->n=map_addnpc(m,nd);
map_addblock(&nd->bl);
+ // clear event timers upon initialise
+ memset(nd->eventqueue, 0, sizeof(nd->eventqueue));
+ for(i = 0; i < MAX_EVENTTIMER; i++)
+ nd->eventtimer[i] = -1;
+
if (evflag) { // ƒCƒxƒ“ƒgŒ^
struct event_data *ev=(struct event_data *)aCalloc(1,sizeof(struct event_data));
ev->nd=nd;
@@ -1750,21 +1855,21 @@ static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line
//-----------------------------------------
- // ƒ‰ƒxƒ‹ƒf[ƒ^‚Ì€”õ
+ // ƒ‰ƒxƒ‹ƒf[ƒ^‚Ì€”õ
if(srcbuf){
// script–{‘Ì‚ª‚ ‚éꇂ̈—
-
+
// ƒ‰ƒxƒ‹ƒf[ƒ^‚̃Rƒ“ƒo[ƒg
label_db=script_get_label_db();
strdb_foreach(label_db,npc_convertlabel_db,nd);
-
+
// ‚à‚¤Žg‚í‚È‚¢‚̂Ńoƒbƒtƒ@‰ð•ú
- free(srcbuf);
+ aFree(srcbuf);
}else{
// duplicate
-// nd->u.scr.label_list=malloc(sizeof(struct npc_label_list)*label_dupnum);
+// nd->u.scr.label_list=aMallocA(sizeof(struct npc_label_list)*label_dupnum);
// memcpy(nd->u.scr.label_list,label_dup,sizeof(struct npc_label_list)*label_dupnum);
nd->u.scr.label_list=label_dup; // ƒ‰ƒxƒ‹ƒf[ƒ^‹¤—L
@@ -1776,25 +1881,76 @@ static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line
for(i=0;i<nd->u.scr.label_list_num;i++){
char *lname=nd->u.scr.label_list[i].name;
int pos=nd->u.scr.label_list[i].pos;
-
+
if ((lname[0]=='O' || lname[0]=='o')&&(lname[1]=='N' || lname[1]=='n')) {
+/*
+I rearrange the code so this is just for commenting; remove it if you have enough if it [Shinomori]
struct event_data *ev;
char *buf;
// ƒGƒNƒXƒ|[ƒg‚³‚ê‚é
ev=(struct event_data *)aCalloc(1,sizeof(struct event_data));
- buf=(char *)aCalloc(50,sizeof(char));
+why allocing 50 chars ?
+ buf=(char *)aCallocA(50,sizeof(char));
+why checking here?
+lname is identical to nd->u.scr.label_list[i].name which is only 24 chars so check for strlen should be 23
if (strlen(lname)>24) {
- printf("npc_parse_script: label name error !\n");
+ printf("npc_parse_script: label name error (%s) !\n", current_file);
exit(1);
}else{
+ //struct event_data *ev2;
ev->nd=nd;
ev->pos=pos;
sprintf(buf,"%s::%s",nd->exname,lname);
+ //ev2 = strdb_search(ev_db,buf);
+ //if(ev2 != NULL) {
+ // printf("npc_parse_script : duplicate event %s\n",buf);
+ // aFree(ev2);
+ //}
+you are sure reentering the same database key will overwrite the existing entry?
strdb_insert(ev_db,buf,ev);
+anyway instead of removing data from the db and inserting a new one
+wouldn't it be easier just not to insert the new duplicate event, it is a duplicate anyway?
+ }
+*/
+ // this check is useless here because the buffer is only 24 chars
+ // and already overwritten if this is here is reached
+ // I leave the check anyway but place it correctly to npc_convertlabel_db
+ if (strlen(lname)>23) {
+ printf("npc_parse_script: label name longer than 23 chars! '%s' (%s)\n", lname, current_file);
+ exit(1);
+ }else{
+ struct event_data *ev;
+ struct event_data *ev2;
+ char *buf;
+ // ƒGƒNƒXƒ|[ƒg‚³‚ê‚é
+
+ // 51 comes from: 24 for npc name + 24 for label + 2 for a "::" and 1 for EOS
+ //buf=(char *)aMalloc(51,sizeof(char));
+ // but to save some memory we alloc only the really necessary space
+ buf=(char *)aMalloc( (3+strlen(nd->exname)+strlen(lname))*sizeof(char));
+ sprintf(buf,"%s::%s",nd->exname,lname);
+
+ // search the label in ev_db;
+ // remember the label is max 50 chars + eos; see the strdb_init below
+ ev2 = (struct event_data *)strdb_search(ev_db,buf);
+ if(ev2 != NULL) {
+ printf("npc_parse_script : duplicate event %s (%s)\n",buf, current_file);
+
+ // just skip the label insertion and free the alloced buffer
+ aFree(buf);
+ }
+ else
+ { // generate the data and insert it
+ ev=(struct event_data *)aCalloc(1,sizeof(struct event_data));
+ ev->nd=nd;
+ ev->pos=pos;
+ strdb_insert(ev_db,buf,ev);
+ }
+
}
}
}
-
+
//-----------------------------------------
// ƒ‰ƒxƒ‹ƒf[ƒ^‚©‚çƒ^ƒCƒ}[ƒCƒxƒ“ƒgŽæ‚èž‚Ý
for(i=0;i<nd->u.scr.label_list_num;i++){
@@ -1806,7 +1962,7 @@ static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line
struct npc_timerevent_list *te=nd->u.scr.timer_event;
int j,k=nd->u.scr.timeramount;
if(te==NULL)
- te=(struct npc_timerevent_list *)aCalloc(1,sizeof(struct npc_timerevent_list));
+ te=(struct npc_timerevent_list *)aCallocA(1,sizeof(struct npc_timerevent_list));
else
te=(struct npc_timerevent_list *)aRealloc( te, sizeof(struct npc_timerevent_list) * (k+1) );
for(j=0;j<k;j++){
@@ -1824,7 +1980,7 @@ static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line
nd->u.scr.nexttimer=-1;
nd->u.scr.timerid=-1;
-
+
return 0;
}
@@ -1843,7 +1999,7 @@ static int npc_parse_function(char *w1,char *w2,char *w3,char *w4,char *first_li
char *p;
// ƒXƒNƒŠƒvƒg‚̉ðÍ
- srcbuf=(char *)aCalloc(srcsize,sizeof(char));
+ srcbuf=(char *)aCallocA(srcsize,sizeof(char));
if (strchr(first_line,'{')) {
strcpy(srcbuf,strchr(first_line,'{'));
startline=*lines;
@@ -1870,14 +2026,14 @@ static int npc_parse_function(char *w1,char *w2,char *w3,char *w4,char *first_li
} else
strcat(srcbuf,line);
}
- script=parse_script(srcbuf,startline);
+ script= parse_script((unsigned char *) srcbuf,startline);
if (script==NULL) {
// script parse error?
- free(srcbuf);
+ aFree(srcbuf);
return 1;
}
- p=(char *)aCalloc(50,sizeof(char));
+ p=(char *)aCallocA(50,sizeof(char));
strncpy(p,w3,50);
strdb_insert(script_get_userfunc_db(),p,script);
@@ -1885,10 +2041,10 @@ static int npc_parse_function(char *w1,char *w2,char *w3,char *w4,char *first_li
// label_db=script_get_label_db();
// ‚à‚¤Žg‚í‚È‚¢‚̂Ńoƒbƒtƒ@‰ð•ú
- free(srcbuf);
-
+ aFree(srcbuf);
+
// printf("function %s => %p\n",p,script);
-
+
return 0;
}
@@ -1899,7 +2055,7 @@ static int npc_parse_function(char *w1,char *w2,char *w3,char *w4,char *first_li
*/
int npc_parse_mob(char *w1,char *w2,char *w3,char *w4)
{
- int m,x,y,xs,ys,class,num,delay1,delay2,level;
+ int m,x,y,xs,ys,class_,num,delay1,delay2,level;
int i;
char mapname[24];
char mobname[24];
@@ -1910,7 +2066,7 @@ int npc_parse_mob(char *w1,char *w2,char *w3,char *w4)
delay1=delay2=0;
// ˆø”‚̌”ƒ`ƒFƒbƒN
if (sscanf(w1,"%[^,],%d,%d,%d,%d",mapname,&x,&y,&xs,&ys) < 3 ||
- sscanf(w4,"%d,%d,%d,%d,%s",&class,&num,&delay1,&delay2,eventname) < 2 ) {
+ sscanf(w4,"%d,%d,%d,%d,%s",&class_,&num,&delay1,&delay2,eventname) < 2 ) {
printf("bad monster line : %s\n",w3);
return 1;
}
@@ -1925,13 +2081,13 @@ int npc_parse_mob(char *w1,char *w2,char *w3,char *w4)
for(i=0;i<num;i++) {
md=(struct mob_data *)aCalloc(1,sizeof(struct mob_data));
- if(class>4000) { // large/tiny mobs [Valaris]
+ if(class_>4000) { // large/tiny mobs [Valaris]
md->size=2;
- class-=4000;
+ class_-=4000;
}
- else if(class>2000) {
+ else if(class_>2000) {
md->size=1;
- class-=2000;
+ class_-=2000;
}
md->bl.prev=NULL;
@@ -1940,19 +2096,16 @@ int npc_parse_mob(char *w1,char *w2,char *w3,char *w4)
md->bl.x=x;
md->bl.y=y;
- if(sscanf(w3,"%[^,],%d",mobname,&level) > 1) {
- if(strcmp(mobname,"--en--")==0)
- memcpy(md->name,mob_db[class].name,24);
- else if(strcmp(mobname,"--ja--")==0)
- memcpy(md->name,mob_db[class].jname,24);
+ if(sscanf(w3,"%[^,],%d",mobname,&level) > 1)
md->level=level;
- }
-
- else
- memcpy(md->name,w3,24);
+ if(strcmp(mobname,"--en--")==0)
+ memcpy(md->name,mob_db[class_].name,24);
+ else if(strcmp(mobname,"--ja--")==0)
+ memcpy(md->name,mob_db[class_].jname,24);
+ else memcpy(md->name,mobname,24);
md->n = i;
- md->base_class = md->class = class;
+ md->base_class = md->class_ = class_;
md->bl.id=npc_get_new_npc_id();
md->m =m;
md->x0=x;
@@ -1966,9 +2119,9 @@ int npc_parse_mob(char *w1,char *w2,char *w3,char *w4)
md->timer = -1;
md->target_id=0;
md->attacked_id=0;
- md->speed=mob_db[class].speed;
+ md->speed=mob_db[class_].speed;
- if (mob_db[class].mode&0x02)
+ if (mob_db[class_].mode&0x02)
md->lootitem=(struct item *)aCalloc(LOOTITEM_SIZE,sizeof(struct item));
else
md->lootitem=NULL;
@@ -2013,7 +2166,7 @@ static int npc_parse_mapflag(char *w1,char *w2,char *w3,char *w4)
//ƒ}ƒbƒvƒtƒ‰ƒO
if ( strcmpi(w3,"nosave")==0) {
if (strcmp(w4,"SavePoint")==0) {
- memcpy(map[m].save.map,"SavePoint",16);
+ memcpy(map[m].save.map,"SavePoint",10);
map[m].save.x=-1;
map[m].save.y=-1;
}else if (sscanf(w4,"%[^,],%d,%d",savemap,&savex,&savey)==3) {
@@ -2106,19 +2259,19 @@ static int npc_parse_mapflag(char *w1,char *w2,char *w3,char *w4)
}
else if (strcmpi(w3,"noicewall")==0) { // noicewall [Valaris]
map[m].flag.noicewall=1;
- }
+ }
else if (strcmpi(w3,"snow")==0) { // snow [Valaris]
map[m].flag.snow=1;
- }
+ }
else if (strcmpi(w3,"fog")==0) { // fog [Valaris]
map[m].flag.fog=1;
- }
+ }
else if (strcmpi(w3,"sakura")==0) { // sakura [Valaris]
map[m].flag.sakura=1;
- }
+ }
else if (strcmpi(w3,"leaves")==0) { // leaves [Valaris]
map[m].flag.leaves=1;
- }
+ }
else if (strcmpi(w3,"rain")==0) { // rain [Valaris]
map[m].flag.rain=1;
}
@@ -2128,15 +2281,116 @@ static int npc_parse_mapflag(char *w1,char *w2,char *w3,char *w4)
else if (strcmpi(w3,"nogo")==0) { // celest
map[m].flag.nogo=1;
}
-
+
+ return 0;
+}
+
+void npc_parsesrcfile(char *name)
+{
+ int m, lines = 0;
+ char line[1024];
+
+ FILE *fp = fopen (name,"r");
+ if (fp == NULL) {
+ ShowError ("File not found : %s\n", name);
+ exit(1);
+ }
+ current_file = name;
+
+ while (fgets(line, 1020, fp)) {
+ char w1[1024], w2[1024], w3[1024], w4[1024], mapname[1024];
+ int i, j, w4pos, count;
+ lines++;
+
+ if (line[0] == '/' && line[1] == '/')
+ continue;
+ // •s—v‚ȃXƒy[ƒX‚âƒ^ƒu‚̘A‘±‚Í‹l‚ß‚é
+ for (i = j = 0; line[i]; i++) {
+ if (line[i]==' ') {
+ if (!((line[i+1] && (isspace(line[i+1]) || line[i+1]==',')) ||
+ (j && line[j-1]==',')))
+ line[j++]=' ';
+ } else if (line[i]=='\t') {
+ if (!(j && line[j-1]=='\t'))
+ line[j++]='\t';
+ } else
+ line[j++]=line[i];
+ }
+ // ʼn‚̓^ƒu‹æØ‚è‚Ń`ƒFƒbƒN‚µ‚Ă݂ÄAƒ_ƒ‚È‚çƒXƒy[ƒX‹æØ‚è‚ÅŠm”F
+ if ((count = sscanf(line,"%[^\t]\t%[^\t]\t%[^\t\r\n]\t%n%[^\t\r\n]", w1, w2, w3, &w4pos, w4)) < 3 &&
+ (count = sscanf(line,"%s%s%s%n%s", w1, w2, w3, &w4pos, w4)) < 3) {
+ continue;
+ }
+ // ƒ}ƒbƒv‚Ì‘¶ÝŠm”F
+ if (strcmp(w1,"-") !=0 && strcmpi(w1,"function") != 0 ){
+ sscanf(w1,"%[^,]",mapname);
+ m = map_mapname2mapid(mapname);
+ if (strlen(mapname)>16 || m<0) {
+ // "mapname" is not assigned to this server
+ continue;
+ }
+ }
+ if (strcmpi(w2,"warp") == 0 && count > 3) {
+ npc_parse_warp(w1,w2,w3,w4);
+ } else if (strcmpi(w2,"shop") == 0 && count > 3) {
+ npc_parse_shop(w1,w2,w3,w4);
+ } else if (strcmpi(w2,"script") == 0 && count > 3) {
+ if (strcmpi(w1,"function") == 0) {
+ npc_parse_function(w1,w2,w3,w4,line+w4pos,fp,&lines);
+ } else {
+ npc_parse_script(w1,w2,w3,w4,line+w4pos,fp,&lines);
+ }
+ } else if ((i = 0, sscanf(w2,"duplicate%n",&i), (i > 0 && w2[i] == '(')) && count > 3) {
+ npc_parse_script(w1,w2,w3,w4,line+w4pos,fp,&lines);
+ } else if (strcmpi(w2,"monster") == 0 && count > 3) {
+ npc_parse_mob(w1,w2,w3,w4);
+ } else if (strcmpi(w2,"mapflag") == 0 && count >= 3) {
+ npc_parse_mapflag(w1,w2,w3,w4);
+ }
+ }
+ fclose(fp);
+
+ return;
+}
+
+static int npc_read_indoors(void)
+{
+ char *buf,*p;
+ int s, m;
+
+ buf=(char *) grfio_reads("data\\indoorrswtable.txt",&s);
+
+ if(buf==NULL)
+ return -1;
+
+ buf[s]=0;
+ for(p=buf;p-buf<s;){
+ char buf2[64];
+
+ if(sscanf(p,"%[^#]#",buf2) == 1){
+ char map_name[64] = "";
+ strncpy(map_name, buf2, strlen(buf2) - 4);
+ strcat(map_name, ".gat");
+ if ((m = map_mapname2mapid(map_name)) >= 0)
+ map[m].flag.indoors=1;
+ }
+
+ p=strchr(p,10);
+ if(!p) break;
+ p++;
+ }
+ aFree(buf);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","data\\indoorrswtable.txt");
+ ShowStatus(tmp_output);
+
return 0;
}
static int ev_db_final(void *key,void *data,va_list ap)
{
- free(data);
- if(strstr(key,"::")!=NULL)
- free(key);
+ aFree(data);
+ if(strstr((const char *) key,"::")!=NULL)
+ aFree(key);
return 0;
}
static int npcname_db_final(void *key,void *data,va_list ap)
@@ -2144,6 +2398,75 @@ static int npcname_db_final(void *key,void *data,va_list ap)
return 0;
}
/*==========================================
+ *
+ *------------------------------------------
+ */
+int npc_cleanup_sub (struct block_list *bl, va_list ap) {
+ nullpo_retr(0, bl);
+
+ switch(bl->type) {
+ case BL_NPC:
+ npc_unload((struct npc_data *)bl);
+ break;
+ case BL_MOB:
+ mob_unload((struct mob_data *)bl);
+ break;
+ }
+
+ return 0;
+}
+int npc_reload(void)
+{
+ struct npc_src_list *nsl;
+ int m, last_npc_id;
+ time_t last_time = time(0);
+ int busy = 0;
+ char c = '-';
+
+ for (m = 0; m < map_num; m++) {
+ map_foreachinarea(npc_cleanup_sub, m, 0, 0, map[m].xs, map[m].ys, 0);
+ map[m].npc_num = 0;
+ }
+ if(ev_db)
+ strdb_final(ev_db,ev_db_final);
+ if(npcname_db)
+ strdb_final(npcname_db,npcname_db_final);
+
+ // anything else we should cleanup?
+ // Reloading npc's now
+ ev_db = strdb_init(51);
+ npcname_db = strdb_init(24);
+ ev_db->release = ev_release;
+ npc_warp = npc_shop = npc_script = npc_mob = 0;
+ last_npc_id = npc_id;
+
+ for (nsl = npc_src_first; nsl; nsl = nsl->next) {
+ npc_parsesrcfile(nsl->name);
+ printf("\r");
+ ShowStatus("Loading NPCs... Working: ");
+ if (last_time != time(0)) {
+ last_time = time(0);
+ switch(busy) {
+ case 0: c='\\'; busy++; break;
+ case 1: c='|'; busy++; break;
+ case 2: c='/'; busy++; break;
+ case 3: c='-'; busy=0;
+ }
+ }
+ printf("[%c]",c);
+ fflush(stdout);
+ }
+ printf("\r");
+ ShowInfo ("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:%30s\n\t-'"
+ CL_WHITE"%d"CL_RESET"' Warps\n\t-'"
+ CL_WHITE"%d"CL_RESET"' Shops\n\t-'"
+ CL_WHITE"%d"CL_RESET"' Scripts\n\t-'"
+ CL_WHITE"%d"CL_RESET"' Mobs\n",
+ npc_id - last_npc_id, "", npc_warp, npc_shop, npc_script, npc_mob);
+
+ return 0;
+}
+/*==========================================
* I—¹
*------------------------------------------
*/
@@ -2153,7 +2476,6 @@ int do_final_npc(void)
struct block_list *bl;
struct npc_data *nd;
struct mob_data *md;
- struct chat_data *cd;
struct pet_data *pd;
if(ev_db)
@@ -2161,53 +2483,27 @@ int do_final_npc(void)
if(npcname_db)
strdb_final(npcname_db,npcname_db_final);
- for(i=START_NPC_NUM;i<npc_id;i++){
- if((bl=map_id2bl(i))){
+ npc_clearsrcfile();
+
+ for (i = START_NPC_NUM; i < npc_id; i++){
+ if((bl = map_id2bl(i))){
if(bl->type == BL_NPC && (nd = (struct npc_data *)bl)){
- if(nd->chat_id && (cd=(struct chat_data*)map_id2bl(nd->chat_id))){
- free(cd);
- cd = NULL;
- }
- if(nd->bl.subtype == SCRIPT){
- if(nd->u.scr.timer_event)
- free(nd->u.scr.timer_event);
- if(nd->u.scr.src_id==0){
- if(nd->u.scr.script){
- free(nd->u.scr.script);
- nd->u.scr.script=NULL;
- }
- if(nd->u.scr.label_list){
- free(nd->u.scr.label_list);
- nd->u.scr.label_list = NULL;
- }
- }
- }
- free(nd);
- nd = NULL;
- }else if(bl->type == BL_MOB && (md = (struct mob_data *)bl)){
- if(md->lootitem){
- free(md->lootitem);
+ npc_unload(nd);
+ }else if (bl->type == BL_MOB && (md = (struct mob_data *)bl)){
+ if (md->lootitem){
+ aFree(md->lootitem);
md->lootitem = NULL;
}
- free(md);
+ aFree(md);
md = NULL;
}else if(bl->type == BL_PET && (pd = (struct pet_data *)bl)){
- free(pd);
+ aFree(pd);
pd = NULL;
}
}
}
-
- return 0;
-}
-
-void ev_release(struct dbn *db, int which)
-{
- if (which & 0x1)
- free(db->key);
- if (which & 0x2)
- free(db->data);
+ return 0;
}
/*==========================================
@@ -2217,86 +2513,56 @@ void ev_release(struct dbn *db, int which)
int do_init_npc(void)
{
struct npc_src_list *nsl;
- FILE *fp;
- char line[1024];
- int m,lines;
-
- ev_db=strdb_init(24);
- npcname_db=strdb_init(24);
-
- ev_db->release = ev_release;
-
- memset(&ev_tm_b,-1,sizeof(ev_tm_b));
-
- for(nsl=npc_src_first;nsl;nsl=nsl->next) {
- if(nsl->prev){
- free(nsl->prev);
+ time_t last_time = time(0);
+ int busy = 0;
+ char c = '-';
+
+ // indoorrswtable.txt and etcinfo.txt [Celest]
+ if (battle_config.indoors_override_grffile)
+ npc_read_indoors();
+ //npc_read_weather();
+
+ // comparing only the first 24 chars of labels that are 50 chars long isn't that nice
+ // will cause "duplicated" labels where actually no dup is...
+ //ev_db=strdb_init(24);
+ ev_db = strdb_init(51);
+ npcname_db = strdb_init(24);
+ ev_db->release = ev_release;
+
+ memset(&ev_tm_b, -1, sizeof(ev_tm_b));
+
+ for (nsl = npc_src_first; nsl; nsl = nsl->next) {
+ /*if(nsl->prev){ // [Shinomori]
+ aFree(nsl->prev);
nsl->prev = NULL;
- }
- fp=fopen(nsl->name,"r");
- if (fp==NULL) {
- printf("file not found : %s\n",nsl->name);
- exit(1);
- }
- lines=0;
- while(fgets(line,1020,fp)) {
- char w1[1024],w2[1024],w3[1024],w4[1024],mapname[1024];
- int i,j,w4pos,count;
- lines++;
-
- if (line[0] == '/' && line[1] == '/')
- continue;
- // •s—v‚ȃXƒy[ƒX‚âƒ^ƒu‚̘A‘±‚Í‹l‚ß‚é
- for(i=j=0;line[i];i++) {
- if (line[i]==' ') {
- if (!((line[i+1] && (isspace(line[i+1]) || line[i+1]==',')) ||
- (j && line[j-1]==',')))
- line[j++]=' ';
- } else if (line[i]=='\t') {
- if (!(j && line[j-1]=='\t'))
- line[j++]='\t';
- } else
- line[j++]=line[i];
- }
- // ʼn‚̓^ƒu‹æØ‚è‚Ń`ƒFƒbƒN‚µ‚Ă݂ÄAƒ_ƒ‚È‚çƒXƒy[ƒX‹æØ‚è‚ÅŠm”F
- if ((count=sscanf(line,"%[^\t]\t%[^\t]\t%[^\t\r\n]\t%n%[^\t\r\n]",w1,w2,w3,&w4pos,w4)) < 3 &&
- (count=sscanf(line,"%s%s%s%n%s",w1,w2,w3,&w4pos,w4)) < 3) {
- continue;
- }
- // ƒ}ƒbƒv‚Ì‘¶ÝŠm”F
- if( strcmp(w1,"-")!=0 && strcmpi(w1,"function")!=0 ){
- sscanf(w1,"%[^,]",mapname);
- m = map_mapname2mapid(mapname);
- if (strlen(mapname)>16 || m<0) {
- // "mapname" is not assigned to this server
- continue;
- }
- }
- if (strcmpi(w2,"warp")==0 && count > 3) {
- npc_parse_warp(w1,w2,w3,w4);
- } else if (strcmpi(w2,"shop")==0 && count > 3) {
- npc_parse_shop(w1,w2,w3,w4);
- } else if (strcmpi(w2,"script")==0 && count > 3) {
- if( strcmpi(w1,"function")==0 ){
- npc_parse_function(w1,w2,w3,w4,line+w4pos,fp,&lines);
- }else{
- npc_parse_script(w1,w2,w3,w4,line+w4pos,fp,&lines);
- }
- } else if ( (i=0,sscanf(w2,"duplicate%n",&i), (i>0 && w2[i]=='(')) && count > 3) {
- npc_parse_script(w1,w2,w3,w4,line+w4pos,fp,&lines);
- } else if (strcmpi(w2,"monster")==0 && count > 3) {
- npc_parse_mob(w1,w2,w3,w4);
- } else if (strcmpi(w2,"mapflag")==0 && count >= 3) {
- npc_parse_mapflag(w1,w2,w3,w4);
+ }*/
+ //
+ npc_parsesrcfile(nsl->name);
+ current_file = NULL;
+ printf("\r");
+ ShowStatus("Loading NPCs... Working: ");
+ if (last_time != time(0)) {
+ last_time = time(0);
+ switch(busy) {
+ case 0: c='\\'; busy++; break;
+ case 1: c='|'; busy++; break;
+ case 2: c='/'; busy++; break;
+ case 3: c='-'; busy=0;
}
}
- fclose(fp);
+ printf("[%c]",c);
+ fflush(stdout);
// printf("\rLoading NPCs [%d]: %-54s",npc_id-START_NPC_NUM,nsl->name);
// fflush(stdout);
}
- printf("\rNPCs Loaded: %d [Warps:%d Shops:%d Scripts:%d Mobs:%d]\n",
- npc_id-START_NPC_NUM,npc_warp,npc_shop,npc_script,npc_mob);
-
+ printf("\r");
+ ShowInfo ("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:%30s\n\t-'"
+ CL_WHITE"%d"CL_RESET"' Warps\n\t-'"
+ CL_WHITE"%d"CL_RESET"' Shops\n\t-'"
+ CL_WHITE"%d"CL_RESET"' Scripts\n\t-'"
+ CL_WHITE"%d"CL_RESET"' Mobs\n",
+ npc_id - START_NPC_NUM, "", npc_warp, npc_shop, npc_script, npc_mob);
+
add_timer_func_list(npc_walktimer,"npc_walktimer"); // [Valaris]
add_timer_func_list(npc_event_timer,"npc_event_timer");
add_timer_func_list(npc_event_do_clock,"npc_event_do_clock");
diff --git a/src/map/npc.h b/src/map/npc.h
index 4f0c43cba..2f81345d7 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -8,6 +8,10 @@
#define WARP_DEBUG_CLASS 722
#define INVISIBLE_CLASS 32767
+#ifdef PCRE_SUPPORT
+void npc_chat_finalize(struct npc_data *nd);
+#endif
+int npc_chat_sub(struct block_list *bl, va_list ap);
int npc_event_dequeue(struct map_session_data *sd);
int npc_event_timer(int tid,unsigned int tick,int id,int data);
int npc_event(struct map_session_data *sd,const char *npcname,int);
@@ -22,6 +26,7 @@ int npc_buylist(struct map_session_data *,int,unsigned short *);
int npc_selllist(struct map_session_data *,int,unsigned short *);
int npc_parse_mob(char *w1,char *w2,char *w3,char *w4);
int npc_parse_warp(char *w1,char *w2,char *w3,char *w4);
+int npc_globalmessage(const char *name,char *mes);
int npc_enable(const char *name,int flag);
struct npc_data* npc_name2id(const char *name);
@@ -37,16 +42,21 @@ void npc_delsrcfile(char *);
int do_final_npc(void);
int do_init_npc(void);
int npc_event_do_oninit(void);
-int npc_do_ontimer(int,struct map_session_data *,int);
+int npc_do_ontimer(int,int);
int npc_event_doall(const char *name);
int npc_event_do(const char *name);
+int npc_event_doall_id(const char *name, int id);
-int npc_timerevent_start(struct npc_data *nd);
+int npc_timerevent_start(struct npc_data *nd, int rid);
int npc_timerevent_stop(struct npc_data *nd);
int npc_gettimerevent_tick(struct npc_data *nd);
int npc_settimerevent_tick(struct npc_data *nd,int newtimer);
-int npc_delete(struct npc_data *nd);
+int npc_remove_map(struct npc_data *nd);
+int npc_unload(struct npc_data *nd);
+int npc_reload(void);
+
+extern char *current_file;
#endif
diff --git a/src/map/npc_chat.c b/src/map/npc_chat.c
new file mode 100644
index 000000000..5ec8540ae
--- /dev/null
+++ b/src/map/npc_chat.c
@@ -0,0 +1,502 @@
+#ifdef PCRE_SUPPORT
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#ifdef __WIN32
+#define __USE_W32_SOCKETS
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+#include <time.h>
+
+#include "../common/timer.h"
+#include "../common/malloc.h"
+#include "../common/version.h"
+#include "../common/nullpo.h"
+#include "../common/showmsg.h"
+
+#include "map.h"
+#include "status.h"
+#include "npc.h"
+#include "chat.h"
+#include "script.h"
+#include "battle.h"
+
+#include "pcre.h"
+
+/**
+ * Written by MouseJstr in a vision... (2/21/2005)
+ *
+ * This allows you to make npc listen for spoken text (global
+ * messages) and pattern match against that spoken text using perl
+ * regular expressions.
+ *
+ * Please feel free to copy this code into your own personal ragnarok
+ * servers or distributions but please leave my name. Also, please
+ * wait until I've put it into the main eA branch which means I
+ * believe it is ready for distribution.
+ *
+ * So, how do people use this?
+ *
+ * The first and most important function is defpattern
+ *
+ * defpattern 1, "[^:]+: (.*) loves (.*)", "label";
+ *
+ * this defines a new pattern in set 1 using perl syntax
+ * (http://www.troubleshooters.com/codecorn/littperl/perlreg.htm)
+ * and tells it to jump to the supplied label when the pattern
+ * is matched.
+ *
+ * each of the matched Groups will result in a variable being
+ * set ($p1$ through $p9$ with $p0$ being the entire string)
+ * before the script gets executed.
+ *
+ * activatepset 1;
+ *
+ * This activates a set of patterns.. You can have many pattern
+ * sets defined and many active all at once. This feature allows
+ * you to set up "conversations" and ever changing expectations of
+ * the pattern matcher
+ *
+ * deactivatepset 1;
+ *
+ * turns off a pattern set;
+ *
+ * deactivatepset -1;
+ *
+ * turns off ALL pattern sets;
+ *
+ * deletepset 1;
+ *
+ * deletes a pset
+ */
+
+/* Structure containing all info associated with a single pattern
+ block */
+
+struct pcrematch_entry {
+ struct pcrematch_entry *next_;
+ char *pattern_;
+ pcre *pcre_;
+ pcre_extra *pcre_extra_;
+ char *label_;
+};
+
+/* A set of patterns that can be activated and deactived with a single
+ command */
+
+struct pcrematch_set {
+ struct pcrematch_set *next_, *prev_;
+ struct pcrematch_entry *head_;
+ int setid_;
+};
+
+/*
+ * Entire data structure hung off a NPC
+ *
+ * The reason I have done it this way (a void * in npc_data and then
+ * this) was to reduce the number of patches that needed to be applied
+ * to a ragnarok distribution to bring this code online. I
+ * also wanted people to be able to grab this one file to get updates
+ * without having to do a large number of changes.
+ */
+
+struct npc_parse {
+ struct pcrematch_set *active_;
+ struct pcrematch_set *inactive_;
+};
+
+
+/**
+ * delete everythign associated with a entry
+ *
+ * This does NOT do the list management
+ */
+
+void finalize_pcrematch_entry(struct pcrematch_entry *e) {
+ free(e->pcre_);
+ free(e->pcre_extra_);
+ aFree(e->pattern_);
+ aFree(e->label_);
+}
+
+/**
+ * Lookup (and possibly create) a new set of patterns by the set id
+ */
+static struct pcrematch_set * lookup_pcreset(struct npc_data *nd,int setid)
+{
+ struct pcrematch_set *pcreset;
+ struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb;
+ if (npcParse == NULL)
+ nd->chatdb = npcParse = (struct npc_parse *)
+ aCalloc(sizeof(struct npc_parse), 1);
+
+ pcreset = npcParse->active_;
+
+ while (pcreset != NULL) {
+ if (pcreset->setid_ == setid)
+ break;
+ pcreset = pcreset->next_;
+ }
+ if (pcreset == NULL)
+ pcreset = npcParse->inactive_;
+
+ while (pcreset != NULL) {
+ if (pcreset->setid_ == setid)
+ break;
+ pcreset = pcreset->next_;
+ }
+
+ if (pcreset == NULL) {
+ pcreset = (struct pcrematch_set *)
+ aCalloc(sizeof(struct pcrematch_set), 1);
+ pcreset->next_ = npcParse->inactive_;
+ if (pcreset->next_ != NULL)
+ pcreset->next_->prev_ = pcreset;
+ pcreset->prev_ = 0;
+ npcParse->inactive_ = pcreset;
+ pcreset->setid_ = setid;
+ }
+
+ return pcreset;
+}
+
+/**
+ * activate a set of patterns.
+ *
+ * if the setid does not exist, this will silently return
+ */
+
+static void activate_pcreset(struct npc_data *nd,int setid) {
+ struct pcrematch_set *pcreset;
+ struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb;
+ if (npcParse == NULL)
+ return; // Nothing to activate...
+ pcreset = npcParse->inactive_;
+ while (pcreset != NULL) {
+ if (pcreset->setid_ == setid)
+ break;
+ pcreset = pcreset->next_;
+ }
+ if (pcreset == NULL)
+ return; // not in inactive list
+ if (pcreset->next_ != NULL)
+ pcreset->next_->prev_ = pcreset->prev_;
+ if (pcreset->prev_ != NULL)
+ pcreset->prev_->next_ = pcreset->next_;
+ else
+ npcParse->inactive_ = pcreset->next_;
+
+ pcreset->prev_ = NULL;
+ pcreset->next_ = npcParse->active_;
+ if (pcreset->next_ != NULL)
+ pcreset->next_->prev_ = pcreset;
+ npcParse->active_ = pcreset;
+}
+
+/**
+ * deactivate a set of patterns.
+ *
+ * if the setid does not exist, this will silently return
+ */
+
+static void deactivate_pcreset(struct npc_data *nd,int setid) {
+ struct pcrematch_set *pcreset;
+ struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb;
+ if (npcParse == NULL)
+ return; // Nothing to deactivate...
+ if (setid == -1) {
+ while(npcParse->active_ != NULL)
+ deactivate_pcreset(nd, npcParse->active_->setid_);
+ return;
+ }
+ pcreset = npcParse->active_;
+ while (pcreset != NULL) {
+ if (pcreset->setid_ == setid)
+ break;
+ pcreset = pcreset->next_;
+ }
+ if (pcreset == NULL)
+ return; // not in active list
+ if (pcreset->next_ != NULL)
+ pcreset->next_->prev_ = pcreset->prev_;
+ if (pcreset->prev_ != NULL)
+ pcreset->prev_->next_ = pcreset->next_;
+ else
+ npcParse->active_ = pcreset->next_;
+
+ pcreset->prev_ = NULL;
+ pcreset->next_ = npcParse->inactive_;
+ if (pcreset->next_ != NULL)
+ pcreset->next_->prev_ = pcreset;
+ npcParse->inactive_ = pcreset;
+}
+
+/**
+ * delete a set of patterns.
+ */
+static void delete_pcreset(struct npc_data *nd,int setid) {
+ int active = 1;
+ struct pcrematch_set *pcreset;
+ struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb;
+ if (npcParse == NULL)
+ return; // Nothing to deactivate...
+ pcreset = npcParse->active_;
+ while (pcreset != NULL) {
+ if (pcreset->setid_ == setid)
+ break;
+ pcreset = pcreset->next_;
+ }
+ if (pcreset == NULL) {
+ active = 0;
+ pcreset = npcParse->inactive_;
+ while (pcreset != NULL) {
+ if (pcreset->setid_ == setid)
+ break;
+ pcreset = pcreset->next_;
+ }
+ }
+ if (pcreset == NULL)
+ return;
+
+ if (pcreset->next_ != NULL)
+ pcreset->next_->prev_ = pcreset->prev_;
+ if (pcreset->prev_ != NULL)
+ pcreset->prev_->next_ = pcreset->next_;
+ else if(active == 1)
+ npcParse->active_ = pcreset->next_;
+ else
+ npcParse->inactive_ = pcreset->next_;
+
+ pcreset->prev_ = NULL;
+ pcreset->next_ = NULL;
+
+ while (pcreset->head_) {
+ struct pcrematch_entry *n = pcreset->head_->next_;;
+ finalize_pcrematch_entry(pcreset->head_);
+ pcreset->head_ = n;
+ }
+
+ aFree(pcreset);
+}
+
+/**
+ * create a new pattern entry
+ */
+static struct pcrematch_entry *create_pcrematch_entry(struct pcrematch_set * set) {
+ struct pcrematch_entry * e = (struct pcrematch_entry *)
+ aCalloc(sizeof(struct pcrematch_entry), 1);
+ struct pcrematch_entry * last = set->head_;
+
+ // Normally we would have just stuck it at the end of the list but
+ // this doesn't sink up with peoples usage pattern. They wanted
+ // the items defined first to have a higher priority then the
+ // items defined later.. as a result, we have to do some work up
+ // front..
+
+ /* if we are the first pattern, stick us at the end */
+ if (last == NULL) {
+ set->head_ = e;
+ return e;
+ }
+
+ /* Look for the last entry */
+ while (last->next_ != NULL)
+ last = last->next_;
+
+ last->next_ = e;
+ e->next_ = NULL;
+
+ return e;
+}
+
+/**
+ * define/compile a new pattern
+ */
+
+void npc_chat_def_pattern(struct npc_data *nd, int setid,
+ const char *pattern, const char *label)
+{
+ const char *err;
+ int erroff;
+
+ struct pcrematch_set * s = lookup_pcreset(nd, setid);
+ struct pcrematch_entry *e = create_pcrematch_entry(s);
+ e->pattern_ = aStrdup(pattern);
+ e->label_ = aStrdup(label);
+ e->pcre_ = pcre_compile(pattern, PCRE_CASELESS, &err, &erroff, NULL);
+ e->pcre_extra_ = pcre_study(e->pcre_, 0, &err);
+}
+
+/**
+ * Delete everything associated with a NPC concerning the pattern
+ * matching code
+ *
+ * this could be more efficent but.. how often do you do this?
+ */
+void npc_chat_finalize(struct npc_data *nd)
+{
+ struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb;
+ if (npcParse == NULL)
+ return;
+
+ while(npcParse->active_)
+ delete_pcreset(nd, npcParse->active_->setid_);
+
+ while(npcParse->inactive_)
+ delete_pcreset(nd, npcParse->inactive_->setid_);
+}
+
+/**
+ * Handler called whenever a global message is spoken in a NPC's area
+ */
+int npc_chat_sub(struct block_list *bl, va_list ap)
+{
+ struct npc_data *nd = (struct npc_data *)bl;
+ struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb;
+ unsigned char *msg;
+ int len, pos, i;
+ struct map_session_data *sd;
+ struct npc_label_list *lst;
+ struct pcrematch_set *pcreset;
+
+ // Not interested in anything you might have to say...
+ if (npcParse == NULL || npcParse->active_ == NULL)
+ return 0;
+
+ msg = va_arg(ap,unsigned char*);
+ len = va_arg(ap,int);
+ sd = va_arg(ap,struct map_session_data *);
+
+ // grab the active list
+ pcreset = npcParse->active_;
+
+ // interate across all active sets
+ while (pcreset != NULL) {
+ struct pcrematch_entry *e = pcreset->head_;
+ // interate across all patterns in that set
+ while (e != NULL) {
+ int offsets[20];
+ char buf[255];
+ // perform pattern match
+ int r = pcre_exec(e->pcre_, e->pcre_extra_, msg, len, 0,
+ 0, offsets, sizeof(offsets) / sizeof(offsets[0]));
+ if (r >= 0) {
+ // save out the matched strings
+ switch (r) {
+ case 10:
+ memcpy(buf, &msg[offsets[18]], offsets[19]);
+ buf[offsets[19]] = '\0';
+ set_var(sd, "$p9$", buf);
+ case 9:
+ memcpy(buf, &msg[offsets[16]], offsets[17]);
+ buf[offsets[17]] = '\0';
+ set_var(sd, "$p8$", buf);
+ case 8:
+ memcpy(buf, &msg[offsets[14]], offsets[15]);
+ buf[offsets[15]] = '\0';
+ set_var(sd, "$p7$", buf);
+ case 7:
+ memcpy(buf, &msg[offsets[12]], offsets[13]);
+ buf[offsets[13]] = '\0';
+ set_var(sd, "$p6$", buf);
+ case 6:
+ memcpy(buf, &msg[offsets[10]], offsets[11]);
+ buf[offsets[11]] = '\0';
+ set_var(sd, "$p5$", buf);
+ case 5:
+ memcpy(buf, &msg[offsets[8]], offsets[9]);
+ buf[offsets[9]] = '\0';
+ set_var(sd, "$p4$", buf);
+ case 4:
+ memcpy(buf, &msg[offsets[6]], offsets[7]);
+ buf[offsets[7]] = '\0';
+ set_var(sd, "$p3$", buf);
+ case 3:
+ memcpy(buf, &msg[offsets[4]], offsets[5]);
+ buf[offsets[5]] = '\0';
+ set_var(sd, "$p2$", buf);
+ case 2:
+ memcpy(buf, &msg[offsets[2]], offsets[3]);
+ buf[offsets[3]] = '\0';
+ set_var(sd, "$p1$", buf);
+ case 1:
+ memcpy(buf, &msg[offsets[0]], offsets[1]);
+ buf[offsets[1]] = '\0';
+ set_var(sd, "$p0$", buf);
+ }
+
+ // find the target label.. this sucks..
+ lst=nd->u.scr.label_list;
+ pos = -1;
+ for (i = 0; i < nd->u.scr.label_list_num; i++) {
+ if (strncmp(lst[i].name, e->label_, sizeof(lst[i].name)) == 0) {
+ pos = lst[i].pos;
+ break;
+ }
+ }
+ if (pos == -1) {
+ printf("Unable to find label: %s", e->label_);
+ // unable to find label... do something..
+ return 0;
+ }
+ // run the npc script
+ run_script(nd->u.scr.script,pos,sd->bl.id,nd->bl.id);
+ return 0;
+ }
+ e = e->next_;
+ }
+ pcreset = pcreset->next_;
+ }
+
+ return 0;
+}
+
+// Various script builtins used to support these functions
+
+int buildin_defpattern(struct script_state *st) {
+ int setid=conv_num(st,& (st->stack->stack_data[st->start+2]));
+ char *pattern=conv_str(st,& (st->stack->stack_data[st->start+3]));
+ char *label=conv_str(st,& (st->stack->stack_data[st->start+4]));
+ struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid);
+
+ npc_chat_def_pattern(nd, setid, pattern, label);
+
+ return 0;
+}
+
+int buildin_activatepset(struct script_state *st) {
+ int setid=conv_num(st,& (st->stack->stack_data[st->start+2]));
+ struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid);
+
+ activate_pcreset(nd, setid);
+
+ return 0;
+}
+int buildin_deactivatepset(struct script_state *st) {
+ int setid=conv_num(st,& (st->stack->stack_data[st->start+2]));
+ struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid);
+
+ deactivate_pcreset(nd, setid);
+
+ return 0;
+}
+int buildin_deletepset(struct script_state *st) {
+ int setid=conv_num(st,& (st->stack->stack_data[st->start+2]));
+ struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid);
+
+ delete_pcreset(nd, setid);
+
+ return 0;
+}
+
+
+#endif
diff --git a/src/map/party.c b/src/map/party.c
index 82b77cf6b..7eb3f02dc 100644
--- a/src/map/party.c
+++ b/src/map/party.c
@@ -30,7 +30,7 @@ int party_send_xyhp_timer(int tid,unsigned int tick,int id,int data);
*/
static int party_db_final(void *key,void *data,va_list ap)
{
- free(data);
+ aFree(data);
return 0;
}
void do_final_party(void)
@@ -49,7 +49,7 @@ void do_init_party(void)
// ŒŸõ
struct party *party_search(int party_id)
{
- return numdb_search(party_db,party_id);
+ return (struct party *) numdb_search(party_db,party_id);
}
int party_searchname_sub(void *key,void *data,va_list ap)
{
@@ -69,12 +69,12 @@ struct party* party_searchname(char *str)
return p;
}
// 쬗v‹
-int party_create(struct map_session_data *sd,char *name)
+int party_create(struct map_session_data *sd,char *name,int item,int item2)
{
nullpo_retr(0, sd);
if(sd->status.party_id==0)
- intif_create_party(sd,name);
+ intif_create_party(sd,name,item,item2);
else
clif_party_created(sd,2);
return 0;
@@ -91,7 +91,7 @@ int party_created(int account_id,int fail,int party_id,char *name)
if(fail==0){
struct party *p;
sd->status.party_id=party_id;
- if((p=numdb_search(party_db,party_id))!=NULL){
+ if((p=(struct party *) numdb_search(party_db,party_id))!=NULL){
printf("party: id already exists!\n");
exit(1);
}
@@ -121,7 +121,7 @@ int party_check_member(struct party *p)
nullpo_retr(0, p);
for(i=0;i<fd_max;i++){
- if(session[i] && (sd=session[i]->session_data) && sd->state.auth){
+ if(session[i] && (sd=(struct map_session_data *) session[i]->session_data) && sd->state.auth){
if(sd->status.party_id==p->party_id){
int j,f=1;
for(j=0;j<MAX_PARTY;j++){ // ƒp[ƒeƒB‚Ƀf[ƒ^‚ª‚ ‚é‚©Šm”F
@@ -149,7 +149,7 @@ int party_recv_noinfo(int party_id)
int i;
struct map_session_data *sd;
for(i=0;i<fd_max;i++){
- if(session[i] && (sd=session[i]->session_data) && sd->state.auth){
+ if(session[i] && (sd=(struct map_session_data *) session[i]->session_data) && sd->state.auth){
if(sd->status.party_id==party_id)
sd->status.party_id=0;
}
@@ -164,7 +164,7 @@ int party_recv_info(struct party *sp)
nullpo_retr(0, sp);
- if((p=numdb_search(party_db,sp->party_id))==NULL){
+ if((p=(struct party *) numdb_search(party_db,sp->party_id))==NULL){
p=(struct party *)aCalloc(1,sizeof(struct party));
numdb_insert(party_db,sp->party_id,p);
@@ -175,7 +175,7 @@ int party_recv_info(struct party *sp)
for(i=0;i<MAX_PARTY;i++){ // sd‚ÌÝ’è
struct map_session_data *sd = map_id2sd(p->member[i].account_id);
- p->member[i].sd=(sd!=NULL && sd->status.party_id==p->party_id)?sd:NULL;
+ p->member[i].sd=(sd!=NULL && sd->status.party_id==p->party_id && !sd->state.waitingdisconnect)?sd:NULL;
}
clif_party_info(p,-1);
@@ -250,11 +250,13 @@ int party_reply_invite(struct map_session_data *sd,int account_id,int flag)
// ƒp[ƒeƒB‚ª’ljÁ‚³‚ꂽ
int party_member_added(int party_id,int account_id,int flag)
{
- struct map_session_data *sd= map_id2sd(account_id),*sd2;
- if(sd==NULL && flag==0){
- if(battle_config.error_log)
- printf("party: member added error %d is not online\n",account_id);
- intif_party_leave(party_id,account_id); // ƒLƒƒƒ‰‘¤‚É“o˜^‚Å‚«‚È‚©‚Á‚½‚½‚ß’E‘Þ—v‹‚ðo‚·
+ struct map_session_data *sd = map_id2sd(account_id),*sd2;
+ if(sd == NULL){
+ if (flag == 0) {
+ if(battle_config.error_log)
+ printf("party: member added error %d is not online\n",account_id);
+ intif_party_leave(party_id,account_id); // ƒLƒƒƒ‰‘¤‚É“o˜^‚Å‚«‚È‚©‚Á‚½‚½‚ß’E‘Þ—v‹‚ðo‚·
+ }
return 0;
}
sd2=map_id2sd(sd->party_invite_account);
@@ -417,7 +419,7 @@ int party_recv_movemap(int party_id,int account_id,char *map,int online,int lv)
for(i=0;i<MAX_PARTY;i++){ // sdÄÝ’è
struct map_session_data *sd= map_id2sd(p->member[i].account_id);
- p->member[i].sd=(sd!=NULL && sd->status.party_id==p->party_id)?sd:NULL;
+ p->member[i].sd=(sd!=NULL && sd->status.party_id==p->party_id && !sd->state.waitingdisconnect)?sd:NULL;
}
party_send_xy_clear(p); // À•WÄ’Ê’m—v¿
@@ -481,6 +483,7 @@ int party_send_message(struct map_session_data *sd,char *mes,int len)
if(sd->status.party_id==0)
return 0;
intif_party_message(sd->status.party_id,sd->status.account_id,mes,len);
+ party_recv_message(sd->status.party_id,sd->status.account_id,mes,len);
return 0;
}
@@ -583,16 +586,23 @@ int party_exp_share(struct party *p,int map,int base_exp,int job_exp,int zeny)
nullpo_retr(0, p);
- for(i=c=0;i<MAX_PARTY;i++)
- if((sd=p->member[i].sd)!=NULL && sd->bl.m==map)
+ for (i=c=0; i < MAX_PARTY; i++)
+ if ((sd = p->member[i].sd) != NULL && p->member[i].online && sd->bl.m == map /*&& session[sd->fd] != NULL*/) // should be done in socket.c
c++;
- if(c==0)
+
+ if(c == 0)
return 0;
- for(i=0;i<MAX_PARTY;i++)
- if((sd=p->member[i].sd)!=NULL && sd->bl.m==map) {
- pc_gainexp(sd,base_exp/c+1,job_exp/c+1);
- if(battle_config.zeny_from_mobs) // zeny from mobs [Valaris]
- pc_getzeny(sd,zeny/c+1);
+ for (i = 0; i < MAX_PARTY; i++)
+ if ((sd = p->member[i].sd) != NULL && p->member[i].online && sd->bl.m == map /*&& session[sd->fd] != NULL*/) {
+ if (battle_config.idle_no_share && (/* pc_issit(sd) || */ sd->chatID || (sd->idletime < (tick_ - 120))))
+ continue;
+ #ifdef TWILIGHT
+ pc_gainexp(sd,base_exp,job_exp);
+ #else
+ pc_gainexp(sd,(base_exp/c)+1,(job_exp/c)+1);
+ #endif
+ if (battle_config.zeny_from_mobs) // zeny from mobs [Valaris]
+ pc_getzeny(sd,(zeny/c)+1);
}
return 0;
}
diff --git a/src/map/party.h b/src/map/party.h
index 5259df7ff..203dd1057 100644
--- a/src/map/party.h
+++ b/src/map/party.h
@@ -13,7 +13,7 @@ void do_final_party(void);
struct party *party_search(int party_id);
struct party* party_searchname(char *str);
-int party_create(struct map_session_data *sd,char *name);
+int party_create(struct map_session_data *sd,char *name, int item, int item2);
int party_created(int account_id,int fail,int party_id,char *name);
int party_request_info(int party_id);
int party_invite(struct map_session_data *sd,int account_id);
diff --git a/src/map/path.c b/src/map/path.c
index b2e0a78a8..c2b852469 100644
--- a/src/map/path.c
+++ b/src/map/path.c
@@ -168,17 +168,13 @@ static int add_path(int *heap,struct tmp_path *tp,int x,int y,int dist,int dir,i
*/
static int can_place(struct map_data *m,int x,int y,int flag)
{
- int c;
-
nullpo_retr(0, m);
- c=read_gatp(m,x,y);
-
- if(c==1)
- return 0;
- if(!(flag&0x10000) && c==5)
- return 0;
- return 1;
+ if(map_getcellp(m,x,y,CELL_CHKPASS))
+ return 1;
+ else if((flag&0x10000)&&map_getcellp(m,x,y,CELL_CHKGROUND))
+ return 1;
+ return 0;
}
/*==========================================
@@ -246,6 +242,76 @@ int path_blownpos(int m,int x0,int y0,int dx,int dy,int count)
}
/*==========================================
+ * êÀËå×îÍô?ª¬Ê¦Òöª«ªÉª¦ª«ªòÚ÷ª¹
+ *------------------------------------------
+ */
+#define swap(x,y) { int t; t = x; x = y; y = t; }
+int path_search_long(struct shootpath_data *spd,int m,int x0,int y0,int x1,int y1)
+{
+ int dx, dy;
+ int wx = 0, wy = 0;
+ int weight;
+ struct map_data *md;
+
+ if (!map[m].gat)
+ return 0;
+ md = &map[m];
+
+ dx = (x1 - x0);
+ if (dx < 0) {
+ swap(x0, x1);
+ swap(y0, y1);
+ dx = -dx;
+ }
+ dy = (y1 - y0);
+
+ if (spd) {
+ spd->rx = spd->ry = 0;
+ spd->len = 1;
+ spd->x[0] = x0;
+ spd->y[0] = y0;
+ }
+
+ if (map_getcellp(md,x1,y1,CELL_CHKWALL))
+ return 0;
+
+ if (dx > abs(dy)) {
+ weight = dx;
+ if (spd)
+ spd->ry=1;
+ } else {
+ weight = abs(y1 - y0);
+ if (spd)
+ spd->rx=1;
+ }
+
+ while (x0 != x1 || y0 != y1) {
+ if (map_getcellp(md,x0,y0,CELL_CHKWALL))
+ return 0;
+ wx += dx;
+ wy += dy;
+ if (wx >= weight) {
+ wx -= weight;
+ x0 ++;
+ }
+ if (wy >= weight) {
+ wy -= weight;
+ y0 ++;
+ } else if (wy < 0) {
+ wy += weight;
+ y0 --;
+ }
+ if (spd && spd->len<MAX_WALKPATH) {
+ spd->x[spd->len] = x0;
+ spd->y[spd->len] = y0;
+ spd->len++;
+ }
+ }
+
+ return 1;
+}
+
+/*==========================================
* path’Tõ (x0,y0)->(x1,y1)
*------------------------------------------
*/
@@ -262,7 +328,7 @@ int path_search(struct walkpath_data *wpd,int m,int x0,int y0,int x1,int y1,int
if(!map[m].gat)
return -1;
md=&map[m];
- if(x1<0 || x1>=md->xs || y1<0 || y1>=md->ys || (i=read_gatp(md,x1,y1))==1 || i==5)
+ if(x1<0 || x1>=md->xs || y1<0 || y1>=md->ys || map_getcellp(md,x1,y1,CELL_CHKNOPASS))
return -1;
// easy
diff --git a/src/map/pc.c b/src/map/pc.c
index 917bbf0a4..e0c13012d 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -1,4 +1,4 @@
-// $Id: pc.c 101 2004-11-26 5:47:29 PM Celestia $
+// $Id: pc.c 101 2004-12-13 7:23:07 PM Celestia $
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -15,6 +15,7 @@
#include "clif.h"
#include "intif.h"
#include "pc.h"
+#include "status.h"
#include "npc.h"
#include "mob.h"
#include "pet.h"
@@ -43,29 +44,16 @@
#define PVP_CALCRANK_INTERVAL 1000 // PVP‡ˆÊŒvŽZ‚ÌŠÔŠu
-#define STATE_BLIND 0x10
-
-static int max_weight_base[MAX_PC_CLASS];
-static int hp_coefficient[MAX_PC_CLASS];
-static int hp_coefficient2[MAX_PC_CLASS];
-static int hp_sigma_val[MAX_PC_CLASS][MAX_LEVEL];
-static int sp_coefficient[MAX_PC_CLASS];
-static int aspd_base[MAX_PC_CLASS][20];
-static char job_bonus[3][MAX_PC_CLASS][MAX_LEVEL];
static int exp_table[14][MAX_LEVEL];
-static char statp[255][7];
+static short statp[MAX_LEVEL];
-/*static struct {
- int id;
- int max;
- struct {
- short id,lv;
- } need[6];
-} skill_tree[3][MAX_PC_CLASS][100];*/ // moved to pc.h - celest
+extern char msg_table[1000][256];
-static int atkmods[3][20]; // •ŠíATKƒTƒCƒYC³(size_fix.txt)
-static int refinebonus[5][3]; // ¸?ƒ{?ƒiƒXƒe?ƒuƒ‹(refine_db.txt)
-static int percentrefinery[5][10]; // ¸?¬Œ÷—¦(refine_db.txt)
+// h-files are for declarations, not for implementations... [Shinomori]
+struct skill_tree_entry skill_tree[3][25][MAX_SKILL_TREE];
+// timer for night.day implementation
+int day_timer_tid;
+int night_timer_tid;
static int dirx[8]={0,-1,-1,-1,0,1,1,1};
static int diry[8]={1,1,0,-1,-1,-1,0,1};
@@ -89,11 +77,11 @@ int pc_isGM(struct map_session_data *sd) {
if (p == NULL)
return 0;
return p->level;*/
-
+
//For console [Wizputer]
if ( sd->fd == 0 )
return 99;
-
+
for(i = 0; i < GM_num; i++)
if (gm_account[i].account_id == sd->status.account_id)
return gm_account[i].level;
@@ -128,18 +116,12 @@ int pc_set_gm_level(int account_id, int level) {
}
GM_num++;
- gm_account = realloc(gm_account, sizeof(struct gm_account) * GM_num);
+ gm_account = (struct gm_account *) aRealloc(gm_account, sizeof(struct gm_account) * GM_num);
gm_account[GM_num - 1].account_id = account_id;
gm_account[GM_num - 1].level = level;
return 0;
}
-int pc_getrefinebonus(int lv, int type) {
- if (lv >= 0 && lv < 5 && type >= 0 && type < 3)
- return refinebonus[lv][type];
- return 0;
-}
-
static int distance(int x0, int y0, int x1, int y1) {
int dx, dy;
@@ -160,6 +142,7 @@ static int pc_invincible_timer(int tid,unsigned int tick,int id,int data) {
return 0;
}
sd->invincible_timer=-1;
+ skill_unit_move(&sd->bl,tick,1);
return 0;
}
@@ -180,12 +163,12 @@ int pc_delinvincibletimer(struct map_session_data *sd) {
delete_timer(sd->invincible_timer,pc_invincible_timer);
sd->invincible_timer = -1;
}
+ skill_unit_move(&sd->bl,gettick(),1);
return 0;
}
static int pc_spiritball_timer(int tid,unsigned int tick,int id,int data) {
struct map_session_data *sd;
- int i;
if( (sd=(struct map_session_data *)map_id2sd(id)) == NULL || sd->bl.type!=BL_PC )
return 1;
@@ -195,22 +178,26 @@ static int pc_spiritball_timer(int tid,unsigned int tick,int id,int data) {
printf("spirit_timer %d != %d\n",sd->spirit_timer[0],tid);
return 0;
}
- sd->spirit_timer[0]=-1;
- for(i=1;i<sd->spiritball;i++) {
- sd->spirit_timer[i-1] = sd->spirit_timer[i];
- sd->spirit_timer[i] = -1;
+
+ if(sd->spiritball <= 0) {
+ if(battle_config.error_log)
+ printf("Spiritballs are already 0 when pc_spiritball_timer gets called");
+ sd->spiritball = 0;
+ return 0;
}
+
sd->spiritball--;
- if(sd->spiritball < 0)
- sd->spiritball = 0;
+ // I leave this here as bad example [Shinomori]
+ //memcpy( &sd->spirit_timer[0], &sd->spirit_timer[1], sizeof(sd->spirit_timer[0]) * sd->spiritball );
+ memmove( sd->spirit_timer+0, sd->spirit_timer+1, (sd->spiritball)*sizeof(int) );
+ sd->spirit_timer[sd->spiritball]=-1;
+
clif_spiritball(sd);
return 0;
}
int pc_addspiritball(struct map_session_data *sd,int interval,int max) {
- int i;
-
nullpo_retr(0, sd);
if(max > MAX_SKILL_LEVEL)
@@ -219,16 +206,13 @@ int pc_addspiritball(struct map_session_data *sd,int interval,int max) {
sd->spiritball = 0;
if(sd->spiritball >= max) {
- if(sd->spirit_timer[0] != -1) {
+ if(sd->spirit_timer[0] != -1)
delete_timer(sd->spirit_timer[0],pc_spiritball_timer);
- sd->spirit_timer[0] = -1;
- }
- for(i=1;i<max;i++) {
- sd->spirit_timer[i-1] = sd->spirit_timer[i];
- sd->spirit_timer[i] = -1;
- }
- }
- else
+ // I leave this here as bad example [Shinomori]
+ //memcpy( &sd->spirit_timer[0], &sd->spirit_timer[1], sizeof(sd->spirit_timer[0]) * (sd->spiritball - 1));
+ memmove( sd->spirit_timer+0, sd->spirit_timer+1, (sd->spiritball - 1)*sizeof(int) );
+ //sd->spirit_timer[sd->spiritball-1] = -1; // intentionally, but will be overwritten
+ } else
sd->spiritball++;
sd->spirit_timer[sd->spiritball-1] = add_timer(gettick()+interval,pc_spiritball_timer,sd->bl.id,0);
@@ -276,13 +260,18 @@ int pc_setrestartvalue(struct map_session_data *sd,int type) {
nullpo_retr(0, sd);
- s_class = pc_calc_base_job(sd->status.class);
+ s_class = pc_calc_base_job(sd->status.class_);
//-----------------------
// Ž€–S‚µ‚½
- if(sd->special_state.restart_full_recover) { // ƒIƒVƒŠƒXƒJ?ƒh
+ if(sd->special_state.restart_full_recover || // ƒIƒVƒŠƒXƒJ?ƒh
+ sd->state.snovice_flag == 4) { // [Celest]
sd->status.hp=sd->status.max_hp;
sd->status.sp=sd->status.max_sp;
+ if (sd->state.snovice_flag == 4) {
+ sd->state.snovice_flag = 0;
+ status_change_start(&sd->bl,SkillStatusChangeTable[MO_STEELBODY],1,0,0,0,skill_get_time(MO_STEELBODY,1),0 );
+ }
}
else {
if(s_class.job == 0 && battle_config.restart_hp_rate < 50) { //ƒmƒr‚Í”¼•ª‰ñ•œ
@@ -310,7 +299,7 @@ int pc_setrestartvalue(struct map_session_data *sd,int type) {
/* removed exp penalty on spawn [Valaris] */
- if(type&2 && sd->status.class != 0 && battle_config.zeny_penalty > 0 && !map[sd->bl.m].flag.nozenypenalty) {
+ if(type&2 && sd->status.class_ != 0 && battle_config.zeny_penalty > 0 && !map[sd->bl.m].flag.nozenypenalty) {
int zeny = (int)((double)sd->status.zeny * (double)battle_config.zeny_penalty / 10000.);
if(zeny < 1) zeny = 1;
sd->status.zeny -= zeny;
@@ -378,37 +367,40 @@ int pc_makesavestatus(struct map_session_data *sd)
{
nullpo_retr(0, sd);
- // •ž‚ÌF‚ÍF?•¾ŠQ‚ª‘½‚¢‚̂ŕۑ¶?ۂɂ͂µ‚È‚¢
+ // •bÌF‚ÍF?•¾ŠQ‚ª‘½‚¢‚̂ŕۑ¶?ۂɂ͂µ‚È‚¢
if(!battle_config.save_clothcolor)
sd->status.clothes_color=0;
// Ž€–S?‘Ô‚¾‚Á‚½‚Ì‚Åhp‚ð1AˆÊ’u‚ðƒZ?ƒuꊂÉ?X
- if(pc_isdead(sd)){
- pc_setrestartvalue(sd,0);
- memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point));
- } else {
- memcpy(sd->status.last_point.map,sd->mapname,24);
- sd->status.last_point.x = sd->bl.x;
- sd->status.last_point.y = sd->bl.y;
- }
-
- // ƒZ?ƒu‹ÖŽ~ƒ}ƒbƒv‚¾‚Á‚½‚̂Ŏw’èˆÊ’u‚Ɉړ®
- if(map[sd->bl.m].flag.nosave){
- struct map_data *m=&map[sd->bl.m];
- if(strcmp(m->save.map,"SavePoint")==0)
+ if(!sd->state.waitingdisconnect) {
+ if(pc_isdead(sd)){
+ pc_setrestartvalue(sd,0);
memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point));
- else
- memcpy(&sd->status.last_point,&m->save,sizeof(sd->status.last_point));
+ } else {
+ memcpy(sd->status.last_point.map,sd->mapname,24);
+ sd->status.last_point.x = sd->bl.x;
+ sd->status.last_point.y = sd->bl.y;
+ }
+
+ // ƒZ?ƒu‹ÖŽ~ƒ}ƒbƒv‚¾‚Á‚½‚̂Ŏw’èˆÊ’u‚Ɉړ®
+ if(map[sd->bl.m].flag.nosave){
+ struct map_data *m=&map[sd->bl.m];
+ if(strcmp(m->save.map,"SavePoint")==0)
+ memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point));
+ else
+ memcpy(&sd->status.last_point,&m->save,sizeof(sd->status.last_point));
+ }
}
//ƒ}ƒi?ƒ|ƒCƒ“ƒg‚ªƒvƒ‰ƒX‚¾‚Á‚½ê‡0‚É
if(battle_config.muting_players && sd->status.manner > 0)
sd->status.manner = 0;
+
return 0;
}
/*==========================================
- * Ú?Žž‚̉Šú‰»
+ * Ú?Žb̉Šú‰»
*------------------------------------------
*/
int pc_setnewpc(struct map_session_data *sd, int account_id, int char_id, int login_id1, int client_tick, int sex, int fd) {
@@ -437,7 +429,7 @@ int pc_equippoint(struct map_session_data *sd,int n)
nullpo_retr(0, sd);
- s_class = pc_calc_base_job(sd->status.class);
+ s_class = pc_calc_base_job(sd->status.class_);
if(sd->inventory_data[n]) {
ep = sd->inventory_data[n]->equip;
@@ -543,8 +535,8 @@ int pc_isequip(struct map_session_data *sd,int n)
nullpo_retr(0, sd);
item = sd->inventory_data[n];
- sc_data = battle_get_sc_data(&sd->bl);
- //s_class = pc_calc_base_job(sd->status.class);
+ sc_data = status_get_sc_data(&sd->bl);
+ //s_class = pc_calc_base_job(sd->status.class_);
if( battle_config.gm_allequip>0 && pc_isGM(sd)>=battle_config.gm_allequip )
return 1;
@@ -559,18 +551,18 @@ int pc_isequip(struct map_session_data *sd,int n)
// as it allows all advanced classes to equip items their normal versions
// could equip)
//
- if(((sd->status.class==13 || sd->status.class==4014) && ((1<<7)&item->class) == 0) || // have mounted classes use unmounted equipment [Valaris]
- ((sd->status.class==21 || sd->status.class==4022) && ((1<<14)&item->class) == 0))
+ if(((sd->status.class_==13 || sd->status.class_==4014) && ((1<<7)&item->class_) == 0) || // have mounted classes use unmounted equipment [Valaris]
+ ((sd->status.class_==21 || sd->status.class_==4022) && ((1<<14)&item->class_) == 0))
return 0;
- if(sd->status.class!=13 && sd->status.class!=4014 && sd->status.class!=21 && sd->status.class!=4022)
- if((sd->status.class<=4000 && ((1<<sd->status.class)&item->class) == 0) || (sd->status.class>4000 && sd->status.class<4023 && ((1<<(sd->status.class-4001))&item->class) == 0) ||
- (sd->status.class>=4023 && ((1<<(sd->status.class-4023))&item->class) == 0))
+ if(sd->status.class_!=13 && sd->status.class_!=4014 && sd->status.class_!=21 && sd->status.class_!=4022)
+ if((sd->status.class_<=4000 && ((1<<sd->status.class_)&item->class_) == 0) || (sd->status.class_>4000 && sd->status.class_<4023 && ((1<<(sd->status.class_-4001))&item->class_) == 0) ||
+ (sd->status.class_>=4023 && ((1<<(sd->status.class_-4023))&item->class_) == 0))
return 0;
-// if(((1<<sd->status.class)&item->class) == 0)
+// if(((1<<sd->status.class_)&item->class_) == 0)
// return 0;
- if(map[sd->bl.m].flag.pvp && (item->flag.no_equip==1 || item->flag.no_equip==3))
+ if(map[sd->bl.m].flag.pvp && (item->flag.no_equip&1)) //optimized by Lupus
return 0;
- if(map[sd->bl.m].flag.gvg && (item->flag.no_equip==2 || item->flag.no_equip==3))
+ if(map[sd->bl.m].flag.gvg && (item->flag.no_equip>1)) //optimized by Lupus
return 0;
if(item->equip & 0x0002 && sc_data && sc_data[SC_STRIPWEAPON].timer != -1)
return 0;
@@ -583,69 +575,52 @@ int pc_isequip(struct map_session_data *sd,int n)
return 1;
}
-/*==========================================
- * Weapon Breaking [Valaris]
- *------------------------------------------
- */
-int pc_breakweapon(struct map_session_data *sd)
+//‘•”õ”j‰ó
+int pc_break_equip(struct map_session_data *sd, unsigned short where)
{
- struct item_data* item;
- char output[255];
int i;
+ int sc;
- if(sd==NULL)
- return -1;
- if(sd->unbreakable>=rand()%100)
+ nullpo_retr(-1, sd);
+ if(sd->unbreakable_equip & where)
return 0;
- if(sd->sc_data && sd->sc_data[SC_CP_WEAPON].timer != -1)
+ if(sd->unbreakable >= rand()%100)
return 0;
-
- for(i=0;i<MAX_INVENTORY;i++){
- if(sd->status.inventory[i].equip && sd->status.inventory[i].equip & 0x0002 && !sd->status.inventory[i].attribute==1){
- item=sd->inventory_data[i];
- sd->status.inventory[i].attribute=1;
- pc_unequipitem(sd,i,0,BF_NORMAL);
- sprintf(output, "%s has broken.",item->jname);
- clif_emotion(&sd->bl,23);
- clif_displaymessage(sd->fd, output);
- clif_equiplist(sd);
- return 1;
- }
+ switch (where) {
+ case EQP_WEAPON:
+ sc = SC_CP_WEAPON;
+ break;
+ case EQP_ARMOR:
+ sc = SC_CP_ARMOR;
+ break;
+ case EQP_SHIELD:
+ sc = SC_CP_SHIELD;
+ break;
+ case EQP_HELM:
+ sc = SC_CP_HELM;
+ break;
+ default:
+ return 0;
}
-
- return 0;
-}
-/*==========================================
- * Armor Breaking [Valaris]
- *------------------------------------------
- */
-int pc_breakarmor(struct map_session_data *sd)
-{
- struct item_data* item;
- char output[255];
- int i;
-
- if(sd==NULL)
- return -1;
- if(sd->unbreakable>=rand()%100)
- return 0;
- if(sd->sc_data && sd->sc_data[SC_CP_ARMOR].timer != -1)
+ if(sd->sc_count && sd->sc_data[sc].timer != -1)
return 0;
- for(i=0;i<MAX_INVENTORY;i++){
- if(sd->status.inventory[i].equip && sd->status.inventory[i].equip & 0x0010 && !sd->status.inventory[i].attribute==1){
- item=sd->inventory_data[i];
- sd->status.inventory[i].attribute=1;
- pc_unequipitem(sd,i,0,BF_NORMAL);
- sprintf(output, "%s has broken.",item->jname);
+ for (i=0;i<MAX_INVENTORY;i++) {
+ if (sd->status.inventory[i].equip & where &&
+ sd->status.inventory[i].attribute != 1) {
+ sd->status.inventory[i].attribute = 1;
+ pc_unequipitem(sd,i,3);
+ sprintf(tmp_output, "%s has broken.",sd->inventory_data[i]->jname);
clif_emotion(&sd->bl,23);
- clif_displaymessage(sd->fd, output);
+ clif_displaymessage(sd->fd, tmp_output);
clif_equiplist(sd);
+ break;
}
}
- return 0;
+ return 1;
}
+
/*==========================================
* session id‚É–â‘è–³‚µ
* charŽI‚©‚ç‘—‚ç‚ê‚Ä‚«‚½ƒXƒe?ƒ^ƒX‚ðÝ’è
@@ -663,8 +638,14 @@ int pc_authok(int id, int login_id2, time_t connect_until_time, struct mmo_chars
sd = map_id2sd(id);
nullpo_retr(1, sd);
+ // check if double login occured
+ if(sd->new_fd){
+ // 2dloginó‘Ô‚¾‚Á‚½‚Ì‚ÅA—¼•û—Ž‚·
+ clif_authfail_fd(sd->fd,2); // same id
+ clif_authfail_fd(sd->new_fd,8); // same id
+ return 1;
+ }
sd->login_id2 = login_id2;
-
memcpy(&sd->status, st, sizeof(*st));
if (sd->status.sex != sd->sex) {
@@ -678,21 +659,21 @@ int pc_authok(int id, int login_id2, time_t connect_until_time, struct mmo_chars
sd->bl.prev = sd->bl.next = NULL;
sd->weapontype1 = sd->weapontype2 = 0;
- sd->view_class = sd->status.class;
+ sd->view_class = sd->status.class_;
sd->speed = DEFAULT_WALK_SPEED;
sd->state.dead_sit = 0;
sd->dir = 0;
sd->head_dir = 0;
sd->state.auth = 1;
sd->walktimer = -1;
+ sd->next_walktime = -1;
sd->attacktimer = -1;
sd->followtimer = -1; // [MouseJstr]
sd->skilltimer = -1;
sd->skillitem = -1;
sd->skillitemlv = -1;
sd->invincible_timer = -1;
- sd->sg_count = 0;
-
+
sd->deal_locked = 0;
sd->trade_partner = 0;
@@ -704,11 +685,11 @@ int pc_authok(int id, int login_id2, time_t connect_until_time, struct mmo_chars
sd->inchealspiritsptick = 0;
sd->canact_tick = tick;
sd->canmove_tick = tick;
+ sd->canregen_tick = tick;
sd->attackabletime = tick;
-
+ sd->reg_num = 0;
sd->doridori_counter = 0;
-
- sd->change_level = pc_readglobalreg(sd,"jobchange_level");
+ sd->change_level = pc_readglobalreg(sd,"jobchange_level");
#ifndef TXT_ONLY // mail system [Valaris]
if(battle_config.mail_system)
@@ -719,13 +700,16 @@ int pc_authok(int id, int login_id2, time_t connect_until_time, struct mmo_chars
sd->spirit_timer[i] = -1;
for(i = 0; i < MAX_SKILLTIMERSKILL; i++)
sd->skilltimerskill[i].timer = -1;
+ sd->timerskill_count=0;
+
+ memset(sd->blockskill,0,sizeof(sd->blockskill));
memset(&sd->dev,0,sizeof(struct square));
for(i = 0; i < 5; i++) {
sd->dev.val1[i] = 0;
sd->dev.val2[i] = 0;
}
-
+
// ƒAƒJƒEƒ“ƒg??‚Ì‘—M—v‹
intif_request_accountreg(sd);
@@ -753,7 +737,7 @@ int pc_authok(int id, int login_id2, time_t connect_until_time, struct mmo_chars
// ƒXƒLƒ‹ƒ†ƒjƒbƒg?ŒW‚̉Šú‰»
memset(sd->skillunit, 0, sizeof(sd->skillunit));
- memset(sd->skillunittick, 0, sizeof(sd->skillunittick));
+ memset(sd->skillunittick, 0, sizeof(sd->skillunittick));
// ƒp?ƒeƒB??ŒW‚̉Šú‰»
sd->party_sended = 0;
@@ -771,9 +755,22 @@ int pc_authok(int id, int login_id2, time_t connect_until_time, struct mmo_chars
memset(sd->eventqueue, 0, sizeof(sd->eventqueue));
for(i = 0; i < MAX_EVENTTIMER; i++)
sd->eventtimer[i] = -1;
+ sd->eventcount=0;
// ˆÊ’u‚ÌÝ’è
- pc_setpos(sd,sd->status.last_point.map, sd->status.last_point.x, sd->status.last_point.y, 0);
+ if (pc_setpos(sd,sd->status.last_point.map, sd->status.last_point.x, sd->status.last_point.y, 0) != 0) {
+ if(battle_config.error_log) {
+ char buf[32];
+ sprintf(buf, "Last_point_map %s not found\n", sd->status.last_point.map);
+ ShowError (buf);
+ }
+ // try warping to a default map instead
+ if (pc_setpos(sd, "prontera.gat", 273, 354, 0) != 0) {
+ // if we fail again
+ clif_authfail_fd(sd->fd, 0);
+ return 1;
+ }
+ }
// pet
if (sd->status.pet_id > 0)
@@ -800,6 +797,18 @@ int pc_authok(int id, int login_id2, time_t connect_until_time, struct mmo_chars
//ƒXƒpƒmƒr—pŽ€‚ɃJƒEƒ“ƒ^?‚̃XƒNƒŠƒvƒg??‚©‚ç‚Ì?‚Ýo‚µ‚Æsd‚ւ̃Zƒbƒg
sd->die_counter = pc_readglobalreg(sd,"PC_DIE_COUNTER");
+ // Automated script events
+ if (script_config.event_requires_trigger) {
+ sd->state.event_death = pc_readglobalreg(sd, script_config.die_event_name);
+ sd->state.event_kill = pc_readglobalreg(sd, script_config.kill_event_name);
+ sd->state.event_disconnect = pc_readglobalreg(sd, script_config.logout_event_name);
+ // if script triggers are not required
+ } else {
+ sd->state.event_death = 1;
+ sd->state.event_kill = 1;
+ sd->state.event_disconnect = 1;
+ }
+
if (night_flag == 1 && !map[sd->bl.m].flag.indoors) {
char tmpstr[1024];
strcpy(tmpstr, msg_txt(500)); // Actually, it's the night...
@@ -812,16 +821,28 @@ int pc_authok(int id, int login_id2, time_t connect_until_time, struct mmo_chars
}
// ƒXƒe?ƒ^ƒX‰ŠúŒvŽZ‚È‚Ç
- pc_calcstatus(sd,1);
+ status_calc_pc(sd,1);
if (pc_isGM(sd))
- printf("Connection accepted: character '%s' (account: %d; GM level %d).\n", sd->status.name, sd->status.account_id, pc_isGM(sd));
+ sprintf(tmp_output,"GM Character '"CL_WHITE"%s"CL_RESET"' logged in. (Acc. ID: '"CL_WHITE"%d"CL_RESET"', GM Level '"CL_WHITE"%d"CL_RESET"').\n", sd->status.name, sd->status.account_id, pc_isGM(sd));
else
- printf("Connection accepted: Character '%s' (account: %d).\n", sd->status.name, sd->status.account_id);
+ sprintf(tmp_output,"Character '"CL_WHITE"%s"CL_RESET"' logged in. (Account ID: '"CL_WHITE"%d"CL_RESET"').\n", sd->status.name, sd->status.account_id);
+ ShowInfo(tmp_output);
+
+ if (script_config.event_script_type == 0) {
+ struct npc_data *npc;
+ //printf("pc: OnPCLogin event done. (%d events)\n", npc_event_doall("OnPCLogin") );
+ if ((npc = npc_name2id(script_config.login_event_name))) {
+ run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCLoginNPC
+ sprintf (tmp_output, "Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.login_event_name);
+ ShowStatus(tmp_output);
+ }
+ } else {
+ sprintf (tmp_output, "%d '"CL_WHITE"%s"CL_RESET"' events executed.\n",
+ npc_event_doall_id(script_config.login_event_name, sd->bl.id), script_config.login_event_name);
+ ShowStatus(tmp_output);
+ }
- //printf("pc: OnPCLogin event done. (%d events)\n", npc_event_doall("OnPCLogin") );
- if (npc_name2id("PCLoginEvent"))
- run_script(npc_name2id("PCLoginEvent")->u.scr.script,0,sd->bl.id,npc_name2id("PCLoginEvent")->bl.id); // PCLoginNPC
// Send friends list
clif_friends_list_send(sd);
@@ -838,13 +859,16 @@ int pc_authok(int id, int login_id2, time_t connect_until_time, struct mmo_chars
break;
}
}
- clif_displaymessage(sd->fd, buf);
+ if (battle_config.motd_type)
+ clif_disp_onlyself(sd,buf,strlen(buf));
+ else
+ clif_displaymessage(sd->fd, buf);
}
fclose(fp);
}
else if(battle_config.error_log) {
- sprintf(buf, "%s not found\n", motd_txt);
- ShowWarning (buf);
+ sprintf(tmp_output, "In function pc_atuhok() -> File '"CL_WHITE"%s"CL_RESET"' not found.\n", motd_txt);
+ ShowWarning(tmp_output);
}
}
@@ -874,6 +898,13 @@ int pc_authfail(int id) {
if (sd == NULL)
return 1;
+ if(sd->new_fd){
+ // 2dloginó‘Ô‚¾‚Á‚½‚Ì‚ÅAV‚µ‚¢Ú‘±‚Ì‚Ý—Ž‚·
+ clif_authfail_fd(sd->new_fd,0);
+ sd->new_fd=0;
+ return 0;
+ }
+
clif_authfail_fd(sd->fd, 0);
return 0;
@@ -913,7 +944,7 @@ int pc_calc_skilltree(struct map_session_data *sd)
nullpo_retr(0, sd);
- s_class = pc_calc_base_job(sd->status.class);
+ s_class = pc_calc_base_job(sd->status.class_);
c = s_class.job;
//s = (s_class.upper==1) ? 1 : 0 ; //?¶ˆÈŠO‚Í’Êí‚̃XƒLƒ‹H
s = s_class.upper;
@@ -921,7 +952,10 @@ int pc_calc_skilltree(struct map_session_data *sd)
c = pc_calc_skilltree_normalize_job(c, sd);
for(i=0;i<MAX_SKILL;i++){
- if (sd->status.skill[i].flag != 13) sd->status.skill[i].id=0;
+// if(skill_get_inf2(i) & 0x01)
+// continue;
+ if (sd->status.skill[i].flag != 13)
+ sd->status.skill[i].id=0;
if (sd->status.skill[i].flag && sd->status.skill[i].flag != 13){ // cardƒXƒLƒ‹‚È‚çA
sd->status.skill[i].lv=(sd->status.skill[i].flag==1)?0:sd->status.skill[i].flag-2; // –{?‚Ìlv‚É
sd->status.skill[i].flag=0; // flag‚Í0‚É‚µ‚Ä‚¨‚­
@@ -934,39 +968,60 @@ int pc_calc_skilltree(struct map_session_data *sd)
sd->status.skill[i].id=i;
for(i=210;i<291;i++)
sd->status.skill[i].id=i;
- for(i=304;i<337;i++){
+ for(i=304;i<338;i++){
if(i==331) continue;
sd->status.skill[i].id=i;
}
- if(battle_config.enable_upper_class){ //conf‚Å–³?‚łȂ¯‚ê‚Î?‚Ý?‚Þ
- for(i=355;i<MAX_SKILL;i++)
+ for(i=355;i<411;i++)
sd->status.skill[i].id=i;
- }
- }else{
- // ’Êí‚ÌŒvŽZ
- do{
- flag=0;
- for(i=0;(id=skill_tree[s][c][i].id)>0;i++){
- int j,f=1;
- if(!battle_config.skillfree) {
- for(j=0;j<5;j++) {
- if( skill_tree[s][c][i].need[j].id &&
- pc_checkskill(sd,skill_tree[s][c][i].need[j].id) < skill_tree[s][c][i].need[j].lv)
+ for(i=475;i<480;i++)
+ sd->status.skill[i].id=i;
+ } else {
+ do {
+ flag=0;
+ for(i=0;(id=skill_tree[s][c][i].id)>0;i++){
+ int j,f=1;
+ if(!battle_config.skillfree) {
+ for(j=0;j<5;j++) {
+ if( skill_tree[s][c][i].need[j].id &&
+ pc_checkskill(sd,skill_tree[s][c][i].need[j].id) <
+ skill_tree[s][c][i].need[j].lv) {
+ f=0;
+ break;
+ }
+ }
+ if (sd->status.job_level < skill_tree[s][c][i].joblv)
f=0;
+ else if (id >= 2 && id <= 53 && pc_checkskill(sd, NV_BASIC) < 9)
+ f=0;
+ }
+ if(f && sd->status.skill[id].id==0 ){
+ sd->status.skill[id].id=id;
+ flag=1;
}
}
- if(f && sd->status.skill[id].id==0 ){
- sd->status.skill[id].id=id;
- flag=1;
- }
- }
- }while(flag);
+ } while(flag);
}
// if(battle_config.etc_log)
// printf("calc skill_tree\n");
return 0;
}
+// Make sure all the skills are in the correct condition
+// before persisting to the backend.. [MouseJstr]
+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].id = 0;
+ sd->status.skill[i].lv = 0;
+ sd->status.skill[i].flag = 0;
+ }
+ }
+
+ return 0;
+}
+
int pc_calc_skilltree_normalize_job(int c, struct map_session_data *sd) {
//if((battle_config.skillup_limit) && ((c >= 0 && c < 23) || (c >= 4001 && c < 4023) || (c >= 4023 && c < 4045))) {
if (battle_config.skillup_limit && c >= 0 && c < 23) {
@@ -975,10 +1030,12 @@ int pc_calc_skilltree_normalize_job(int c, struct map_session_data *sd) {
c = 0;
//else if((sd->status.skill_point >= sd->status.job_level && skill_point < 58) && ((c > 6 && c < 23) || (c > 4007 && c < 4023) || (c > 4029 && c < 4045))) {
//else if ((sd->status.skill_point >= sd->status.job_level && skill_point < 58) && (c > 6 && c < 23)) {
- else if ((sd->status.skill_point >= sd->status.job_level && skill_point < sd->change_level+8) && (c > 6 && c < 23)) {
+ else if (sd->status.skill_point >= sd->status.job_level && ((sd->change_level > 0 && skill_point < sd->change_level+8) || skill_point < 58) && (c > 6 && c < 23)) {
switch(c) {
case 7:
+ case 13:
case 14:
+ case 21:
c = 1;
break;
case 8:
@@ -1002,8 +1059,11 @@ int pc_calc_skilltree_normalize_job(int c, struct map_session_data *sd) {
case 17:
c = 6;
break;
- /*case 4008:
+#if 0
+ case 4008:
+ case 4014:
case 4015:
+ case 4022:
c = 4002;
break;
case 4009:
@@ -1028,7 +1088,9 @@ int pc_calc_skilltree_normalize_job(int c, struct map_session_data *sd) {
c = 4007;
break;
case 4030:
+ case 4036:
case 4037:
+ case 4044:
c = 4024;
break;
case 4031:
@@ -1051,7 +1113,8 @@ int pc_calc_skilltree_normalize_job(int c, struct map_session_data *sd) {
case 4035:
case 4043:
c = 4029;
- break;*/
+ break;
+#endif
}
}
}
@@ -1072,1127 +1135,29 @@ int pc_checkweighticon(struct map_session_data *sd)
flag=1;
if(sd->weight*10 >= sd->max_weight*9)
flag=2;
-
+
if(flag==1){
if(sd->sc_data[SC_WEIGHT50].timer==-1)
- skill_status_change_start(&sd->bl,SC_WEIGHT50,0,0,0,0,0,0);
+ status_change_start(&sd->bl,SC_WEIGHT50,0,0,0,0,0,0);
}else{
- skill_status_change_end(&sd->bl,SC_WEIGHT50,-1);
+ status_change_end(&sd->bl,SC_WEIGHT50,-1);
}
if(flag==2){
if(sd->sc_data[SC_WEIGHT90].timer==-1)
- skill_status_change_start(&sd->bl,SC_WEIGHT90,0,0,0,0,0,0);
+ status_change_start(&sd->bl,SC_WEIGHT90,0,0,0,0,0,0);
}else{
- skill_status_change_end(&sd->bl,SC_WEIGHT90,-1);
+ status_change_end(&sd->bl,SC_WEIGHT90,-1);
}
return 0;
}
/*==========================================
- * ƒpƒ‰ƒ?ƒ^ŒvŽZ
- * first==0‚ÌŽžAŒvŽZ?ۂ̃pƒ‰ƒ?ƒ^‚ªŒÄ‚Ño‚µ‘O‚©‚ç
- * ? ‰»‚µ‚½ê‡Ž©“®‚Åsend‚·‚邪A
- * ”\“®“I‚É?‰»‚³‚¹‚½ƒpƒ‰ƒ?ƒ^‚ÍŽ©‘O‚Åsend‚·‚邿‚¤‚É
- *------------------------------------------
- */
-int pc_calcstatus(struct map_session_data* sd,int first)
-{
- int b_speed,b_max_hp,b_max_sp,b_hp,b_sp,b_weight,b_max_weight,b_paramb[6],b_parame[6],b_hit,b_flee;
- int b_aspd,b_watk,b_def,b_watk2,b_def2,b_flee2,b_critical,b_attackrange,b_matk1,b_matk2,b_mdef,b_mdef2,b_class;
- int b_base_atk;
- struct skill b_skill[MAX_SKILL];
- int i,bl,index;
- int skill,aspd_rate,wele,wele_,def_ele,refinedef=0;
- int pele=0,pdef_ele=0;
- int str,dstr,dex;
- struct pc_base_job s_class;
-
- nullpo_retr(0, sd);
-
- //?¶‚â—{Žq‚Ìꇂ̌³‚ÌE‹Æ‚ðŽZo‚·‚é
- s_class = pc_calc_base_job(sd->status.class);
-
- b_speed = sd->speed;
- b_max_hp = sd->status.max_hp;
- b_max_sp = sd->status.max_sp;
- b_hp = sd->status.hp;
- b_sp = sd->status.sp;
- b_weight = sd->weight;
- b_max_weight = sd->max_weight;
- memcpy(b_paramb,&sd->paramb,sizeof(b_paramb));
- memcpy(b_parame,&sd->paramc,sizeof(b_parame));
- memcpy(b_skill,&sd->status.skill,sizeof(b_skill));
- b_hit = sd->hit;
- b_flee = sd->flee;
- b_aspd = sd->aspd;
- b_watk = sd->watk;
- b_def = sd->def;
- b_watk2 = sd->watk2;
- b_def2 = sd->def2;
- b_flee2 = sd->flee2;
- b_critical = sd->critical;
- b_attackrange = sd->attackrange;
- b_matk1 = sd->matk1;
- b_matk2 = sd->matk2;
- b_mdef = sd->mdef;
- b_mdef2 = sd->mdef2;
- b_class = sd->view_class;
- sd->view_class = sd->status.class;
- b_base_atk = sd->base_atk;
-
- pc_calc_skilltree(sd); // ƒXƒLƒ‹ƒcƒŠ?‚ÌŒvŽZ
-
- sd->max_weight = max_weight_base[s_class.job]+sd->status.str*300;
-
- if(first&1) {
- sd->weight=0;
- for(i=0;i<MAX_INVENTORY;i++){
- if(sd->status.inventory[i].nameid==0 || sd->inventory_data[i] == NULL)
- continue;
- sd->weight += sd->inventory_data[i]->weight*sd->status.inventory[i].amount;
- }
- sd->cart_max_weight=battle_config.max_cart_weight;
- sd->cart_weight=0;
- sd->cart_max_num=MAX_CART;
- sd->cart_num=0;
- for(i=0;i<MAX_CART;i++){
- if(sd->status.cart[i].nameid==0)
- continue;
- sd->cart_weight+=itemdb_weight(sd->status.cart[i].nameid)*sd->status.cart[i].amount;
- sd->cart_num++;
- }
- }
-
- memset(sd->paramb,0,sizeof(sd->paramb));
- memset(sd->parame,0,sizeof(sd->parame));
- sd->hit = 0;
- sd->flee = 0;
- sd->flee2 = 0;
- sd->critical = 0;
- sd->aspd = 0;
- sd->watk = 0;
- sd->def = 0;
- sd->mdef = 0;
- sd->watk2 = 0;
- sd->def2 = 0;
- sd->mdef2 = 0;
- sd->status.max_hp = 0;
- sd->status.max_sp = 0;
- sd->attackrange = 0;
- sd->attackrange_ = 0;
- sd->atk_ele = 0;
- sd->def_ele = 0;
- sd->star =0;
- sd->overrefine =0;
- sd->matk1 =0;
- sd->matk2 =0;
- sd->speed = DEFAULT_WALK_SPEED ;
- sd->hprate=100;
- sd->sprate=100;
- sd->castrate=100;
- sd->dsprate=100;
- sd->base_atk=0;
- sd->arrow_atk=0;
- sd->arrow_ele=0;
- sd->arrow_hit=0;
- sd->arrow_range=0;
- sd->nhealhp=sd->nhealsp=sd->nshealhp=sd->nshealsp=sd->nsshealhp=sd->nsshealsp=0;
- memset(sd->addele,0,sizeof(sd->addele));
- memset(sd->addrace,0,sizeof(sd->addrace));
- memset(sd->addsize,0,sizeof(sd->addsize));
- memset(sd->addele_,0,sizeof(sd->addele_));
- memset(sd->addrace_,0,sizeof(sd->addrace_));
- memset(sd->addsize_,0,sizeof(sd->addsize_));
- memset(sd->subele,0,sizeof(sd->subele));
- memset(sd->subrace,0,sizeof(sd->subrace));
- memset(sd->addeff,0,sizeof(sd->addeff));
- memset(sd->addeff2,0,sizeof(sd->addeff2));
- memset(sd->reseff,0,sizeof(sd->reseff));
- memset(&sd->special_state,0,sizeof(sd->special_state));
- memset(sd->weapon_coma_ele,0,sizeof(sd->weapon_coma_ele));
- memset(sd->weapon_coma_race,0,sizeof(sd->weapon_coma_race));
-
- sd->watk_ = 0; //“ñ“—¬—p(?)
- sd->watk_2 = 0;
- sd->atk_ele_ = 0;
- sd->star_ = 0;
- sd->overrefine_ = 0;
-
- sd->aspd_rate = 100;
- sd->speed_rate = 100;
- sd->hprecov_rate = 100;
- sd->sprecov_rate = 100;
- sd->critical_def = 0;
- sd->double_rate = 0;
- sd->near_attack_def_rate = sd->long_attack_def_rate = 0;
- sd->atk_rate = sd->matk_rate = 100;
- sd->ignore_def_ele = sd->ignore_def_race = 0;
- sd->ignore_def_ele_ = sd->ignore_def_race_ = 0;
- sd->ignore_mdef_ele = sd->ignore_mdef_race = 0;
- sd->arrow_cri = 0;
- sd->magic_def_rate = sd->misc_def_rate = 0;
- memset(sd->arrow_addele,0,sizeof(sd->arrow_addele));
- memset(sd->arrow_addrace,0,sizeof(sd->arrow_addrace));
- memset(sd->arrow_addsize,0,sizeof(sd->arrow_addsize));
- memset(sd->arrow_addeff,0,sizeof(sd->arrow_addeff));
- memset(sd->arrow_addeff2,0,sizeof(sd->arrow_addeff2));
- memset(sd->magic_addele,0,sizeof(sd->magic_addele));
- memset(sd->magic_addrace,0,sizeof(sd->magic_addrace));
- memset(sd->magic_subrace,0,sizeof(sd->magic_subrace));
- sd->perfect_hit = 0;
- sd->critical_rate = sd->hit_rate = sd->flee_rate = sd->flee2_rate = 100;
- sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100;
- sd->def_ratio_atk_ele = sd->def_ratio_atk_ele_ = 0;
- sd->def_ratio_atk_race = sd->def_ratio_atk_race_ = 0;
- sd->get_zeny_num = 0;
- sd->add_damage_class_count = sd->add_damage_class_count_ = sd->add_magic_damage_class_count = 0;
- sd->add_def_class_count = sd->add_mdef_class_count = 0;
- sd->monster_drop_item_count = 0;
- memset(sd->add_damage_classrate,0,sizeof(sd->add_damage_classrate));
- memset(sd->add_damage_classrate_,0,sizeof(sd->add_damage_classrate_));
- memset(sd->add_magic_damage_classrate,0,sizeof(sd->add_magic_damage_classrate));
- memset(sd->add_def_classrate,0,sizeof(sd->add_def_classrate));
- memset(sd->add_mdef_classrate,0,sizeof(sd->add_mdef_classrate));
- memset(sd->monster_drop_race,0,sizeof(sd->monster_drop_race));
- memset(sd->monster_drop_itemrate,0,sizeof(sd->monster_drop_itemrate));
- sd->speed_add_rate = sd->aspd_add_rate = 100;
- sd->double_add_rate = sd->perfect_hit_add = sd->get_zeny_add_num = 0;
- sd->splash_range = sd->splash_add_range = 0;
- sd->autospell_id = sd->autospell_lv = sd->autospell_rate = 0;
- sd->hp_drain_rate = sd->hp_drain_per = sd->sp_drain_rate = sd->sp_drain_per = 0;
- sd->hp_drain_rate_ = sd->hp_drain_per_ = sd->sp_drain_rate_ = sd->sp_drain_per_ = 0;
- sd->short_weapon_damage_return = sd->long_weapon_damage_return = 0;
- sd->magic_damage_return = 0; //AppleGirl Was Here
- sd->random_attack_increase_add = sd->random_attack_increase_per = 0;
-
- if(!sd->disguiseflag && sd->disguise) {
- sd->disguise=0;
- clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
- clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
- clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
- clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
- clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
- clif_clearchar(&sd->bl, 9);
- pc_setpos(sd, sd->mapname, sd->bl.x, sd->bl.y, 3);
- }
-
- for(i=0;i<10;i++) {
- index = sd->equip_index[i];
- if(index < 0)
- continue;
- if(i == 9 && sd->equip_index[8] == index)
- continue;
- if(i == 5 && sd->equip_index[4] == index)
- continue;
- if(i == 6 && (sd->equip_index[5] == index || sd->equip_index[4] == index))
- continue;
-
- if(sd->inventory_data[index]) {
- if(sd->inventory_data[index]->type == 4) {
- if(sd->status.inventory[index].card[0]!=0x00ff && sd->status.inventory[index].card[0]!=0x00fe && sd->status.inventory[index].card[0]!=(short)0xff00) {
- int j;
- for(j=0;j<sd->inventory_data[index]->slot;j++){ // ƒJ?ƒh
- int c=sd->status.inventory[index].card[j];
- if(c>0){
- if(i == 8 && sd->status.inventory[index].equip == 0x20)
- sd->state.lr_flag = 1;
- run_script(itemdb_equipscript(c),0,sd->bl.id,0);
- sd->state.lr_flag = 0;
- }
- }
- }
- }
- else if(sd->inventory_data[index]->type==5){ // –h‹ï
- if(sd->status.inventory[index].card[0]!=0x00ff && sd->status.inventory[index].card[0]!=0x00fe && sd->status.inventory[index].card[0]!=(short)0xff00) {
- int j;
- for(j=0;j<sd->inventory_data[index]->slot;j++){ // ƒJ?ƒh
- int c=sd->status.inventory[index].card[j];
- if(c>0)
- run_script(itemdb_equipscript(c),0,sd->bl.id,0);
- }
- }
- }
- }
- }
- wele = sd->atk_ele;
- wele_ = sd->atk_ele_;
- def_ele = sd->def_ele;
- if(sd->status.pet_id > 0) {
- struct pet_data *pd=sd->pd;
- if((pd && battle_config.pet_status_support==1) && (battle_config.pet_equip_required==0 || (battle_config.pet_equip_required && pd->equip > 0))) {
- if(sd->status.pet_id > 0 && sd->petDB && sd->pet.intimate > 0)
- run_script(sd->petDB->script,0,sd->bl.id,0);
- pele = sd->atk_ele;
- pdef_ele = sd->def_ele;
- sd->atk_ele = sd->def_ele = 0;
- }
- }
- memcpy(sd->paramcard,sd->parame,sizeof(sd->paramcard));
-
- // ?”õ•i‚É‚æ‚éƒXƒe?ƒ^ƒX?‰»‚Í‚±‚±‚Å?s
- for(i=0;i<10;i++) {
- index = sd->equip_index[i];
- if(index < 0)
- continue;
- if(i == 9 && sd->equip_index[8] == index)
- continue;
- if(i == 5 && sd->equip_index[4] == index)
- continue;
- if(i == 6 && (sd->equip_index[5] == index || sd->equip_index[4] == index))
- continue;
- if(sd->inventory_data[index]) {
- sd->def += sd->inventory_data[index]->def;
- if(sd->inventory_data[index]->type == 4) {
- int r,wlv = sd->inventory_data[index]->wlv;
- if(i == 8 && sd->status.inventory[index].equip == 0x20) {
- //“ñ“—¬—pƒf?ƒ^“ü—Í
- sd->watk_ += sd->inventory_data[index]->atk;
- sd->watk_2 = (r=sd->status.inventory[index].refine)* // ¸?U?—Í
- refinebonus[wlv][0];
- if( (r-=refinebonus[wlv][2])>0 ) // ‰ß?¸?ƒ{?ƒiƒX
- sd->overrefine_ = r*refinebonus[wlv][1];
-
- if(sd->status.inventory[index].card[0]==0x00ff){ // »‘¢•Ší
- sd->star_ = (sd->status.inventory[index].card[1]>>8); // ¯‚Ì‚©‚¯‚ç
- wele_= (sd->status.inventory[index].card[1]&0x0f); // ? «
- }
- sd->attackrange_ += sd->inventory_data[index]->range;
- sd->state.lr_flag = 1;
- run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0);
- sd->state.lr_flag = 0;
- }
- else { //“ñ“—¬•ŠíˆÈŠO
- sd->watk += sd->inventory_data[index]->atk;
- sd->watk2 += (r=sd->status.inventory[index].refine)* // ¸?U?—Í
- refinebonus[wlv][0];
- if( (r-=refinebonus[wlv][2])>0 ) // ‰ß?¸?ƒ{?ƒiƒX
- sd->overrefine += r*refinebonus[wlv][1];
-
- if(sd->status.inventory[index].card[0]==0x00ff){ // »‘¢•Ší
- sd->star += (sd->status.inventory[index].card[1]>>8); // ¯‚Ì‚©‚¯‚ç
- wele = (sd->status.inventory[index].card[1]&0x0f); // ? «
- }
- sd->attackrange += sd->inventory_data[index]->range;
- run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0);
- }
- }
- else if(sd->inventory_data[index]->type == 5) {
- sd->watk += sd->inventory_data[index]->atk;
- refinedef += sd->status.inventory[index].refine*refinebonus[0][0];
- run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0);
- }
- }
- }
-
- if(sd->equip_index[10] >= 0){ // –î
- index = sd->equip_index[10];
- if(sd->inventory_data[index]){ //‚Ü‚¾?«‚ª“ü‚Á‚Ä‚¢‚È‚¢
- sd->state.lr_flag = 2;
- run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0);
- sd->state.lr_flag = 0;
- sd->arrow_atk += sd->inventory_data[index]->atk;
- }
- }
- sd->def += (refinedef+50)/100;
-
- if(sd->attackrange < 1) sd->attackrange = 1;
- if(sd->attackrange_ < 1) sd->attackrange_ = 1;
- if(sd->attackrange < sd->attackrange_)
- sd->attackrange = sd->attackrange_;
- if(sd->status.weapon == 11)
- sd->attackrange += sd->arrow_range;
- if(wele > 0)
- sd->atk_ele = wele;
- if(wele_ > 0)
- sd->atk_ele_ = wele_;
- if(def_ele > 0)
- sd->def_ele = def_ele;
- if(battle_config.pet_status_support) {
- if(pele > 0 && !sd->atk_ele)
- sd->atk_ele = pele;
- if(pdef_ele > 0 && !sd->def_ele)
- sd->def_ele = pdef_ele;
- }
- sd->double_rate += sd->double_add_rate;
- sd->perfect_hit += sd->perfect_hit_add;
- sd->get_zeny_num += sd->get_zeny_add_num;
- sd->splash_range += sd->splash_add_range;
- if(sd->speed_add_rate != 100)
- sd->speed_rate += sd->speed_add_rate - 100;
- if(sd->aspd_add_rate != 100)
- sd->aspd_rate += sd->aspd_add_rate - 100;
-
- // •ŠíATKƒTƒCƒY•â³ (‰EŽè)
- sd->atkmods[0] = atkmods[0][sd->weapontype1];
- sd->atkmods[1] = atkmods[1][sd->weapontype1];
- sd->atkmods[2] = atkmods[2][sd->weapontype1];
- //•ŠíATKƒTƒCƒY•â³ (¶Žè)
- sd->atkmods_[0] = atkmods[0][sd->weapontype2];
- sd->atkmods_[1] = atkmods[1][sd->weapontype2];
- sd->atkmods_[2] = atkmods[2][sd->weapontype2];
-
- // jobƒ{?ƒiƒX•ª
- for(i=0;i<sd->status.job_level && i<MAX_LEVEL;i++){
- if(job_bonus[s_class.upper][s_class.job][i])
- sd->paramb[job_bonus[s_class.upper][s_class.job][i]-1]++;
- }
-
- if( (skill=pc_checkskill(sd,MC_INCCARRY))>0 ) // skill can be used with an item now, thanks to orn [Valaris]
- sd->max_weight += skill*1000;
-
- if( (skill=pc_checkskill(sd,AC_OWL))>0 ) // ‚Ó‚­‚낤‚Ì–Ú
- sd->paramb[4] += skill;
-
- if((skill=pc_checkskill(sd,BS_HILTBINDING))>0) { // Hilt binding gives +1 str +4 atk
- sd->paramb[0] ++;
- sd->base_atk += 4;
- }
-
- // New guild skills - Celest
- if (sd->status.guild_id > 0) {
- struct guild *g;
- if ((g = guild_search(sd->status.guild_id)) && strcmp(sd->status.name,g->master)==0) {
- if (!sd->sc_data[SC_LEADERSHIP].val4 && guild_checkskill(g, GD_LEADERSHIP)>0) {
- //skill_status_change_start(&sd->bl,SC_LEADERSHIP,1,0,0,0,0,0 );
- skill_unitsetting(&sd->bl,GD_LEADERSHIP,1,sd->bl.x,sd->bl.y,0);
- }
- if (!sd->sc_data[SC_GLORYWOUNDS].val4 && guild_checkskill(g, GD_GLORYWOUNDS)>0) {
- //skill_status_change_start(&sd->bl,SC_GLORYWOUNDS,1,0,0,0,0,0 );
- skill_unitsetting(&sd->bl,GD_GLORYWOUNDS,1,sd->bl.x,sd->bl.y,0);
- }
- if (!sd->sc_data[SC_SOULCOLD].val4 && guild_checkskill(g, GD_SOULCOLD)>0) {
- //skill_status_change_start(&sd->bl,SC_SOULCOLD,1,0,0,0,0,0 );
- skill_unitsetting(&sd->bl,GD_SOULCOLD,1,sd->bl.x,sd->bl.y,0);
- }
- if (!sd->sc_data[SC_HAWKEYES].val4 && guild_checkskill(g, GD_HAWKEYES)>0) {
- //skill_status_change_start(&sd->bl,SC_HAWKEYES,1,0,0,0,0,0 );
- skill_unitsetting(&sd->bl,GD_HAWKEYES,1,sd->bl.x,sd->bl.y,0);
- }
- }
- else {
- if (sd->sc_data[SC_LEADERSHIP].timer != -1)
- sd->paramb[0] += 2;
- if (sd->sc_data[SC_GLORYWOUNDS].timer != -1)
- sd->paramb[2] += 2;
- if (sd->sc_data[SC_SOULCOLD].timer != -1)
- sd->paramb[1] += 2;
- if (sd->sc_data[SC_HAWKEYES].timer != -1)
- sd->paramb[4] += 2;
- if (sd->sc_data[SC_BATTLEORDERS].timer != -1) {
- sd->paramb[0]+= 5;
- sd->paramb[3]+= 5;
- sd->paramb[4]+= 5;
- }
- }
- }
-
- // ƒXƒe?ƒ^ƒX?‰»‚É‚æ‚éŠî–{ƒpƒ‰ƒ?ƒ^•â³
- if(sd->sc_count){
- if(sd->sc_data[SC_CONCENTRATE].timer!=-1 && sd->sc_data[SC_QUAGMIRE].timer == -1){ // W’†—ÍŒüã
- sd->paramb[1]+= (sd->status.agi+sd->paramb[1]+sd->parame[1]-sd->paramcard[1])*(2+sd->sc_data[SC_CONCENTRATE].val1)/100;
- sd->paramb[4]+= (sd->status.dex+sd->paramb[4]+sd->parame[4]-sd->paramcard[4])*(2+sd->sc_data[SC_CONCENTRATE].val1)/100;
- }
- if(sd->sc_data[SC_INCREASEAGI].timer!=-1 && sd->sc_data[SC_QUAGMIRE].timer == -1 && sd->sc_data[SC_DONTFORGETME].timer == -1){ // ‘¬“x?‰Á
- sd->paramb[1]+= 2+sd->sc_data[SC_INCREASEAGI].val1;
- sd->speed -= sd->speed *25/100;
- }
- if(sd->sc_data[SC_DECREASEAGI].timer!=-1) // ‘¬“xŒ¸­(agi‚Íbattle.c‚Å)
- sd->speed = sd->speed *125/100;
- if(sd->sc_data[SC_CLOAKING].timer!=-1) {
- sd->critical_rate += 100; // critical increases
- sd->speed = sd->speed * (sd->sc_data[SC_CLOAKING].val3-sd->sc_data[SC_CLOAKING].val1*3) /100;
- // Ours is accurate enough - refer skill_check_cloaking. ^^
- //sd->speed = (sd->speed*(76+(sd->sc_data[SC_CLOAKING].val1*3)))/100; // Fixed by MiKa & Asa [Lupus]
- }
- //sd->speed = (sd->speed*(76+(sd->sc_data[SC_INCREASEAGI].val1*3)))/100;
- if(sd->sc_data[SC_CHASEWALK].timer!=-1)
- sd->speed = sd->speed * sd->sc_data[SC_CHASEWALK].val3 /100; // slow down by chasewalk
- if(sd->sc_data[SC_BLESSING].timer!=-1){ // ƒuƒŒƒbƒVƒ“ƒO
- sd->paramb[0]+= sd->sc_data[SC_BLESSING].val1;
- sd->paramb[3]+= sd->sc_data[SC_BLESSING].val1;
- sd->paramb[4]+= sd->sc_data[SC_BLESSING].val1;
- }
- if(sd->sc_data[SC_GLORIA].timer!=-1) // ƒOƒƒŠƒA
- sd->paramb[5]+= 30;
- if(sd->sc_data[SC_LOUD].timer!=-1 && sd->sc_data[SC_QUAGMIRE].timer == -1) // ƒ‰ƒEƒhƒ{ƒCƒX
- sd->paramb[0]+= 4;
- if(sd->sc_data[SC_QUAGMIRE].timer!=-1){ // ƒNƒ@ƒOƒ}ƒCƒA
- int agib = (sd->status.agi+sd->paramb[1]+sd->parame[1])*(sd->sc_data[SC_QUAGMIRE].val1*10)/100;
- int dexb = (sd->status.dex+sd->paramb[4]+sd->parame[4])*(sd->sc_data[SC_QUAGMIRE].val1*10)/100;
- sd->paramb[1]-= agib > 50 ? 50 : agib;
- sd->paramb[4]-= dexb > 50 ? 50 : dexb;
- sd->speed = sd->speed*3/2;
- }
- if(sd->sc_data[SC_TRUESIGHT].timer!=-1){ // ƒgƒDƒ‹?ƒTƒCƒg
- sd->paramb[0]+= 5;
- sd->paramb[1]+= 5;
- sd->paramb[2]+= 5;
- sd->paramb[3]+= 5;
- sd->paramb[4]+= 5;
- sd->paramb[5]+= 5;
- }
- if(sd->sc_data[SC_MARIONETTE].timer!=-1){
- sd->paramb[0]-= sd->status.str/2; // bonuses not included
- sd->paramb[1]-= sd->status.agi/2;
- sd->paramb[2]-= sd->status.vit/2;
- sd->paramb[3]-= sd->status.int_/2;
- sd->paramb[4]-= sd->status.dex/2;
- sd->paramb[5]-= sd->status.luk/2;
- }
- else if(sd->sc_data[SC_MARIONETTE2].timer!=-1){
- struct map_session_data *psd = (struct map_session_data *)map_id2bl(sd->sc_data[SC_MARIONETTE2].val3);
- if (psd) { // if partner is found
- sd->paramb[0] += sd->status.str+psd->status.str/2 > 99 ? 99-sd->status.str : psd->status.str/2;
- sd->paramb[1] += sd->status.agi+psd->status.agi/2 > 99 ? 99-sd->status.agi : psd->status.agi/2;
- sd->paramb[2] += sd->status.vit+psd->status.vit/2 > 99 ? 99-sd->status.vit : psd->status.vit/2;
- sd->paramb[3] += sd->status.int_+psd->status.int_/2 > 99 ? 99-sd->status.int_ : psd->status.int_/2;
- sd->paramb[4] += sd->status.dex+psd->status.dex/2 > 99 ? 99-sd->status.dex : psd->status.dex/2;
- sd->paramb[5] += sd->status.luk+psd->status.luk/2 > 99 ? 99-sd->status.luk : psd->status.luk/2;
- }
- }
- }
-
- //1“x‚àŽ€‚ñ‚łȂ¢Job70ƒXƒpƒmƒr‚É+10
- if(s_class.job == 23 && sd->die_counter == 0 && sd->status.job_level >= 70){
- sd->paramb[0]+= 15;
- sd->paramb[1]+= 15;
- sd->paramb[2]+= 15;
- sd->paramb[3]+= 15;
- sd->paramb[4]+= 15;
- sd->paramb[5]+= 15;
- }
- sd->paramc[0]=sd->status.str+sd->paramb[0]+sd->parame[0];
- sd->paramc[1]=sd->status.agi+sd->paramb[1]+sd->parame[1];
- sd->paramc[2]=sd->status.vit+sd->paramb[2]+sd->parame[2];
- sd->paramc[3]=sd->status.int_+sd->paramb[3]+sd->parame[3];
- sd->paramc[4]=sd->status.dex+sd->paramb[4]+sd->parame[4];
- sd->paramc[5]=sd->status.luk+sd->paramb[5]+sd->parame[5];
- for(i=0;i<6;i++)
- if(sd->paramc[i] < 0) sd->paramc[i] = 0;
-
- if(sd->status.weapon == 11 || sd->status.weapon == 13 || sd->status.weapon == 14) {
- str = sd->paramc[4];
- dex = sd->paramc[0];
- }
- else {
- str = sd->paramc[0];
- dex = sd->paramc[4];
- }
- dstr = str/10;
- sd->base_atk += str + dstr*dstr + dex/5 + sd->paramc[5]/5;
- sd->matk1 += sd->paramc[3]+(sd->paramc[3]/5)*(sd->paramc[3]/5);
- sd->matk2 += sd->paramc[3]+(sd->paramc[3]/7)*(sd->paramc[3]/7);
- if(sd->matk1 < sd->matk2) {
- int temp = sd->matk2;
- sd->matk2 = sd->matk1;
- sd->matk1 = temp;
- }
- sd->hit += sd->paramc[4] + sd->status.base_level;
- sd->flee += sd->paramc[1] + sd->status.base_level;
- sd->def2 += sd->paramc[2];
- sd->mdef2 += sd->paramc[3];
- sd->flee2 += sd->paramc[5]+10;
- sd->critical += (sd->paramc[5]*3)+10;
-
- if(sd->base_atk < 1)
- sd->base_atk = 1;
- if(sd->critical_rate != 100)
- sd->critical = (sd->critical*sd->critical_rate)/100;
- if(sd->critical < 10) sd->critical = 10;
- if(sd->hit_rate != 100)
- sd->hit = (sd->hit*sd->hit_rate)/100;
- if(sd->hit < 1) sd->hit = 1;
- if(sd->flee_rate != 100)
- sd->flee = (sd->flee*sd->flee_rate)/100;
- if(sd->flee < 1) sd->flee = 1;
- if(sd->flee2_rate != 100)
- sd->flee2 = (sd->flee2*sd->flee2_rate)/100;
- if(sd->flee2 < 10) sd->flee2 = 10;
- if(sd->def_rate != 100)
- sd->def = (sd->def*sd->def_rate)/100;
- if(sd->def < 0) sd->def = 0;
- if(sd->def2_rate != 100)
- sd->def2 = (sd->def2*sd->def2_rate)/100;
- if(sd->def2 < 1) sd->def2 = 1;
- if(sd->mdef_rate != 100)
- sd->mdef = (sd->mdef*sd->mdef_rate)/100;
- if(sd->mdef < 0) sd->mdef = 0;
- if(sd->mdef2_rate != 100)
- sd->mdef2 = (sd->mdef2*sd->mdef2_rate)/100;
- if(sd->mdef2 < 1) sd->mdef2 = 1;
-
- // “ñ“—¬ ASPD C³
- if (sd->status.weapon <= 16)
- sd->aspd += aspd_base[s_class.job][sd->status.weapon]-(sd->paramc[1]*4+sd->paramc[4])*aspd_base[s_class.job][sd->status.weapon]/1000;
- else
- sd->aspd += (
- (aspd_base[s_class.job][sd->weapontype1]-(sd->paramc[1]*4+sd->paramc[4])*aspd_base[s_class.job][sd->weapontype1]/1000) +
- (aspd_base[s_class.job][sd->weapontype2]-(sd->paramc[1]*4+sd->paramc[4])*aspd_base[s_class.job][sd->weapontype2]/1000)
- ) * 140 / 200;
-
- aspd_rate = sd->aspd_rate;
-
- //U?‘¬“x?‰Á
-
- if( (skill=pc_checkskill(sd,AC_VULTURE))>0){ // ƒƒV‚Ì–Ú
- sd->hit += skill;
- if(sd->status.weapon == 11)
- sd->attackrange += skill;
- }
-
- if( (skill=pc_checkskill(sd,BS_WEAPONRESEARCH))>0) // •Ší?‹†‚Ì–½’†—¦?‰Á
- sd->hit += skill*2;
- if(sd->status.option&2 && (skill = pc_checkskill(sd,RG_TUNNELDRIVE))>0 ) // ƒgƒ“ƒlƒ‹ƒhƒ‰ƒCƒu // ƒgƒ“ƒlƒ‹ƒhƒ‰ƒCƒu
- sd->speed += (1.2*DEFAULT_WALK_SPEED - skill*9);
- if (pc_iscarton(sd) && (skill=pc_checkskill(sd,MC_PUSHCART))>0) // ƒJ?ƒg‚É‚æ‚鑬“x’ቺ
- sd->speed += (10-skill) * (DEFAULT_WALK_SPEED * 0.1);
- else if (pc_isriding(sd)) { // ƒyƒRƒyƒR?‚è‚É‚æ‚鑬“x?‰Á
- sd->speed -= (0.25 * DEFAULT_WALK_SPEED);
- sd->max_weight += 10000;
- }
- if(sd->sc_count){
- if(sd->sc_data[SC_WINDWALK].timer!=-1) //ƒEƒBƒ“ƒhƒEƒH?ƒNŽž‚ÍLv*2%Œ¸ŽZ
- sd->speed -= sd->speed *(sd->sc_data[SC_WINDWALK].val1*2)/100;
- if(sd->sc_data[SC_CARTBOOST].timer!=-1) // ƒJ?ƒgƒu?ƒXƒg
- sd->speed -= (DEFAULT_WALK_SPEED * 20)/100;
- if(sd->sc_data[SC_BERSERK].timer!=-1) //ƒo?ƒT?ƒN’†‚ÍIA‚Æ“¯‚¶‚®‚ç‚¢‘¬‚¢H
- sd->speed -= sd->speed *25/100;
- if(sd->sc_data[SC_WEDDING].timer!=-1) //Œ‹¥’†‚Í?‚­‚Ì‚ª?‚¢
- sd->speed = 2*DEFAULT_WALK_SPEED;
- }
-
- if((skill=pc_checkskill(sd,CR_TRUST))>0) { // ƒtƒFƒCƒX
- sd->status.max_hp += skill*200;
- sd->subele[6] += skill*5;
- }
- if((skill=pc_checkskill(sd,BS_SKINTEMPER))>0)
- {
- sd->subele[0] += skill;
- sd->subele[3] += skill*5;
- }
-
- bl=sd->status.base_level;
-
- sd->status.max_hp += (3500 + bl*hp_coefficient2[s_class.job] + hp_sigma_val[s_class.job][(bl > 0)? bl-1:0])/100 * (100 + sd->paramc[2])/100 + (sd->parame[2] - sd->paramcard[2]);
- if (s_class.upper==1) // [MouseJstr]
- sd->status.max_hp = sd->status.max_hp * 130/100;
- else if (s_class.upper==2)
- sd->status.max_hp = sd->status.max_hp * 70/100;
-
- if(sd->hprate!=100)
- sd->status.max_hp = sd->status.max_hp*sd->hprate/100;
-
- if(sd->sc_data && sd->sc_data[SC_BERSERK].timer!=-1){ // ƒo?ƒT?ƒN
- sd->status.max_hp = sd->status.max_hp * 3;
- // sd->status.hp = sd->status.hp * 3;
- if(sd->status.max_hp > battle_config.max_hp) // removed negative max hp bug by Valaris
- sd->status.max_hp = battle_config.max_hp;
- if(sd->status.hp > battle_config.max_hp) // removed negative max hp bug by Valaris
- sd->status.hp = battle_config.max_hp;
- }
- if(s_class.job == 23 && sd->status.base_level >= 99){
- sd->status.max_hp = sd->status.max_hp + 2000;
- }
-
- if(sd->status.max_hp > battle_config.max_hp) // removed negative max hp bug by Valaris
- sd->status.max_hp = battle_config.max_hp;
- if(sd->status.max_hp <= 0) sd->status.max_hp = 1; // end
-
- // Å‘åSPŒvŽZ
- sd->status.max_sp += ((sp_coefficient[s_class.job] * bl) + 1000)/100 * (100 + sd->paramc[3])/100 + (sd->parame[3] - sd->paramcard[3]);
- if (s_class.upper==1) // [MouseJstr]
- sd->status.max_sp = sd->status.max_sp * 130/100;
- else if (s_class.upper==2)
- sd->status.max_sp = sd->status.max_sp * 70/100;
- if(sd->sprate!=100)
- sd->status.max_sp = sd->status.max_sp*sd->sprate/100;
-
- if((skill=pc_checkskill(sd,HP_MEDITATIO))>0) // ƒƒfƒBƒeƒCƒeƒBƒI
- sd->status.max_sp += sd->status.max_sp*skill/100;
- if((skill=pc_checkskill(sd,HW_SOULDRAIN))>0) /* ƒ\ƒEƒ‹ƒhƒŒƒCƒ“ */
- sd->status.max_sp += sd->status.max_sp*2*skill/100;
-
- if(sd->status.max_sp < 0 || sd->status.max_sp > battle_config.max_sp)
- sd->status.max_sp = battle_config.max_sp;
-
- //Ž©‘R‰ñ•œHP
- sd->nhealhp = 1 + (sd->paramc[2]/5) + (sd->status.max_hp/200);
- if((skill=pc_checkskill(sd,SM_RECOVERY)) > 0) { /* HP‰ñ•œ—ÍŒüã */
- sd->nshealhp = skill*5 + (sd->status.max_hp*skill/500);
- if(sd->nshealhp > 0x7fff) sd->nshealhp = 0x7fff;
- }
- //Ž©‘R‰ñ•œSP
- sd->nhealsp = 1 + (sd->paramc[3]/6) + (sd->status.max_sp/100);
- if(sd->paramc[3] >= 120)
- sd->nhealsp += ((sd->paramc[3]-120)>>1) + 4;
- if((skill=pc_checkskill(sd,MG_SRECOVERY)) > 0) { /* SP‰ñ•œ—ÍŒüã */
- sd->nshealsp = skill*3 + (sd->status.max_sp*skill/500);
- if(sd->nshealsp > 0x7fff) sd->nshealsp = 0x7fff;
- }
-
- if((skill = pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0) {
- sd->nsshealhp = skill*4 + (sd->status.max_hp*skill/500);
- sd->nsshealsp = skill*2 + (sd->status.max_sp*skill/500);
- if(sd->nsshealhp > 0x7fff) sd->nsshealhp = 0x7fff;
- if(sd->nsshealsp > 0x7fff) sd->nsshealsp = 0x7fff;
- }
- if(sd->hprecov_rate != 100) {
- sd->nhealhp = sd->nhealhp*sd->hprecov_rate/100;
- if(sd->nhealhp < 1) sd->nhealhp = 1;
- }
- if(sd->sprecov_rate != 100) {
- sd->nhealsp = sd->nhealsp*sd->sprecov_rate/100;
- if(sd->nhealsp < 1) sd->nhealsp = 1;
- }
- /* if((skill=pc_checkskill(sd,HP_MEDITATIO)) > 0) { // f?fffBfefCfefBfI,I'SPR,A*,I',E`,¡©Z((c)¡®R¢¶n~.©«,E',(c),(c),e'
- sd->nhealsp += 3*skill*(sd->status.max_sp)/100;
- if(sd->nhealsp > 0x7fff) sd->nhealsp = 0x7fff;
- } Increase natural SP regen instead of colossal SP Recovery effect [DracoRPG]*/
-
- // Ží‘°‘Ï«i‚±‚ê‚Å‚¢‚¢‚ÌH ƒfƒBƒoƒCƒ“ƒvƒƒeƒNƒVƒ‡ƒ“‚Æ“¯‚¶?—‚ª‚¢‚é‚©‚àj
- if( (skill=pc_checkskill(sd,SA_DRAGONOLOGY))>0 ){ // ƒhƒ‰ƒSƒmƒƒW?
- skill = skill*4;
- sd->addrace[9]+=skill;
- sd->addrace_[9]+=skill;
- sd->subrace[9]+=skill;
- sd->magic_addrace[9]+=skill;
- sd->magic_subrace[9]-=skill;
- }
-
- //Fleeã¸
- if( (skill=pc_checkskill(sd,TF_MISS))>0 ){ // ‰ñ”ð—¦?‰Á
- if(sd->status.class==6||sd->status.class==4007 || sd->status.class==23){
- sd->flee += skill*3;
- }
- if(sd->status.class==12||sd->status.class==17||sd->status.class==4013||sd->status.class==4018)
- sd->flee += skill*4;
- if(sd->status.class==12||sd->status.class==4013)
- sd->speed -= sd->speed *(skill*1.5)/100;
- }
- if( (skill=pc_checkskill(sd,MO_DODGE))>0 ) // Œ©Ø‚è
- sd->flee += (skill*3)>>1;
-
- // ƒXƒLƒ‹‚âƒXƒe?ƒ^ƒXˆÙí‚É‚æ‚é?‚è‚̃pƒ‰ƒ?ƒ^•â³
- if(sd->sc_count){
- // ATK/DEF?‰»Œ`
- if(sd->sc_data[SC_ANGELUS].timer!=-1) // ƒGƒ“ƒWƒFƒ‰ƒX
- sd->def2 = sd->def2*(110+5*sd->sc_data[SC_ANGELUS].val1)/100;
- if(sd->sc_data[SC_IMPOSITIO].timer!=-1) {// ƒCƒ“ƒ|ƒVƒeƒBƒIƒ}ƒkƒX
- sd->watk += sd->sc_data[SC_IMPOSITIO].val1*5;
- index = sd->equip_index[8];
- if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4)
- sd->watk_ += sd->sc_data[SC_IMPOSITIO].val1*5;
- }
- if(sd->sc_data[SC_PROVOKE].timer!=-1){ // ƒvƒƒ{ƒbƒN
- sd->def2 = sd->def2*(100-6*sd->sc_data[SC_PROVOKE].val1)/100;
- sd->base_atk = sd->base_atk*(100+2*sd->sc_data[SC_PROVOKE].val1)/100;
- sd->watk = sd->watk*(100+2*sd->sc_data[SC_PROVOKE].val1)/100;
- index = sd->equip_index[8];
- if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4)
- sd->watk_ = sd->watk_*(100+2*sd->sc_data[SC_PROVOKE].val1)/100;
- }
- if(sd->sc_data[SC_ENDURE].timer!=-1)
- sd->mdef2 += sd->sc_data[SC_ENDURE].val1;
- if(sd->sc_data[SC_MINDBREAKER].timer!=-1){ // ƒvƒƒ{ƒbƒN
- sd->mdef2 = sd->mdef2*(100-6*sd->sc_data[SC_MINDBREAKER].val1)/100;
- sd->matk1 = sd->matk1*(100+2*sd->sc_data[SC_MINDBREAKER].val1)/100;
- sd->matk2 = sd->matk2*(100+2*sd->sc_data[SC_MINDBREAKER].val1)/100;
- }
- if(sd->sc_data[SC_POISON].timer!=-1) // “Å?‘Ô
- sd->def2 = sd->def2*75/100;
- if(sd->sc_data[SC_DRUMBATTLE].timer!=-1){ // ?‘¾ŒÛ‚Ì‹¿‚«
- sd->watk += sd->sc_data[SC_DRUMBATTLE].val2;
- sd->def += sd->sc_data[SC_DRUMBATTLE].val3;
- index = sd->equip_index[8];
- if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4)
- sd->watk_ += sd->sc_data[SC_DRUMBATTLE].val2;
- }
- if(sd->sc_data[SC_NIBELUNGEN].timer!=-1) { // ƒj?ƒxƒ‹ƒ“ƒO‚ÌŽw—Ö
- index = sd->equip_index[9];
- if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 3)
- sd->watk += sd->sc_data[SC_NIBELUNGEN].val3;
- index = sd->equip_index[8];
- if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 3)
- sd->watk_ += sd->sc_data[SC_NIBELUNGEN].val3;
- if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 4)
- sd->watk += sd->sc_data[SC_NIBELUNGEN].val2;
- index = sd->equip_index[8];
- if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 4)
- sd->watk_ += sd->sc_data[SC_NIBELUNGEN].val2;
- }
-
- if(sd->sc_data[SC_VOLCANO].timer!=-1 && sd->def_ele==3){ // ƒ{ƒ‹ƒP?ƒm
- sd->watk += sd->sc_data[SC_VIOLENTGALE].val3;
- }
-
- if(sd->sc_data[SC_SIGNUMCRUCIS].timer!=-1)
- sd->def = sd->def * (100 - sd->sc_data[SC_SIGNUMCRUCIS].val2)/100;
- if(sd->sc_data[SC_ETERNALCHAOS].timer!=-1) // ƒGƒ^?ƒiƒ‹ƒJƒIƒX
- sd->def=0;
-
- if(sd->sc_data[SC_CONCENTRATION].timer!=-1){ //ƒRƒ“ƒZƒ“ƒgƒŒ?ƒVƒ‡ƒ“
- sd->watk = sd->watk * (100 + 5*sd->sc_data[SC_CONCENTRATION].val1)/100;
- index = sd->equip_index[8];
- if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4)
- sd->watk_ = sd->watk * (100 + 5*sd->sc_data[SC_CONCENTRATION].val1)/100;
- sd->def = sd->def * (100 - 5*sd->sc_data[SC_CONCENTRATION].val1)/100;
- }
-
- if(sd->sc_data[SC_MAGICPOWER].timer!=-1){ //–‚–@—Í?•
- sd->matk1 = sd->matk1*(100+5*sd->sc_data[SC_MAGICPOWER].val1)/100;
- sd->matk2 = sd->matk2*(100+5*sd->sc_data[SC_MAGICPOWER].val1)/100;
- }
- if(sd->sc_data[SC_ATKPOT].timer!=-1)
- sd->watk += sd->sc_data[SC_ATKPOT].val1;
- if(sd->sc_data[SC_MATKPOT].timer!=-1){
- sd->matk1 += sd->sc_data[SC_MATKPOT].val1;
- sd->matk2 += sd->sc_data[SC_MATKPOT].val1;
- }
-
- // ASPD/ˆÚ“®‘¬“x?‰»Œn
- if(sd->sc_data[SC_TWOHANDQUICKEN].timer != -1 && sd->sc_data[SC_QUAGMIRE].timer == -1 && sd->sc_data[SC_DONTFORGETME].timer == -1) // 2HQ
- aspd_rate -= 30;
- if(sd->sc_data[SC_ADRENALINE].timer != -1 && sd->sc_data[SC_TWOHANDQUICKEN].timer == -1 &&
- sd->sc_data[SC_QUAGMIRE].timer == -1 && sd->sc_data[SC_DONTFORGETME].timer == -1) { // ƒAƒhƒŒƒiƒŠƒ“ƒ‰ƒbƒVƒ…
- if(sd->sc_data[SC_ADRENALINE].val2 || !battle_config.party_skill_penaly)
- aspd_rate -= 30;
- else
- aspd_rate -= 25;
- }
- if(sd->sc_data[SC_SPEARSQUICKEN].timer != -1 && sd->sc_data[SC_ADRENALINE].timer == -1 &&
- sd->sc_data[SC_TWOHANDQUICKEN].timer == -1 && sd->sc_data[SC_QUAGMIRE].timer == -1 && sd->sc_data[SC_DONTFORGETME].timer == -1) // ƒXƒsƒAƒNƒBƒbƒPƒ“
- aspd_rate -= sd->sc_data[SC_SPEARSQUICKEN].val2;
- if(sd->sc_data[SC_ASSNCROS].timer!=-1 && // —[—z‚̃AƒTƒVƒ“ƒNƒƒX
- sd->sc_data[SC_TWOHANDQUICKEN].timer==-1 && sd->sc_data[SC_ADRENALINE].timer==-1 && sd->sc_data[SC_SPEARSQUICKEN].timer==-1 &&
- sd->sc_data[SC_DONTFORGETME].timer == -1)
- aspd_rate -= 5+sd->sc_data[SC_ASSNCROS].val1+sd->sc_data[SC_ASSNCROS].val2+sd->sc_data[SC_ASSNCROS].val3;
- if(sd->sc_data[SC_DONTFORGETME].timer!=-1){ // Ž„‚ð–Y‚ê‚È‚¢‚Å
- aspd_rate += sd->sc_data[SC_DONTFORGETME].val1*3 + sd->sc_data[SC_DONTFORGETME].val2 + (sd->sc_data[SC_DONTFORGETME].val3>>16);
- sd->speed= sd->speed*(100+sd->sc_data[SC_DONTFORGETME].val1*2 + sd->sc_data[SC_DONTFORGETME].val2 + (sd->sc_data[SC_DONTFORGETME].val3&0xffff))/100;
- }
- if( sd->sc_data[i=SC_SPEEDPOTION2].timer!=-1 ||
- sd->sc_data[i=SC_SPEEDPOTION1].timer!=-1 ||
- sd->sc_data[i=SC_SPEEDPOTION0].timer!=-1) // ? ‘¬ƒ|?ƒVƒ‡ƒ“
- aspd_rate -= sd->sc_data[i].val2;
-
- // HIT/FLEE?‰»Œn
- if(sd->sc_data[SC_WHISTLE].timer!=-1){ // Œû“J
- sd->flee += sd->flee * (sd->sc_data[SC_WHISTLE].val1
- +sd->sc_data[SC_WHISTLE].val2+(sd->sc_data[SC_WHISTLE].val3>>16))/100;
- sd->flee2+= (sd->sc_data[SC_WHISTLE].val1+sd->sc_data[SC_WHISTLE].val2+(sd->sc_data[SC_WHISTLE].val3&0xffff)) * 10;
- }
- if(sd->sc_data[SC_HUMMING].timer!=-1) // ƒnƒ~ƒ“ƒO
- sd->hit += (sd->sc_data[SC_HUMMING].val1*2+sd->sc_data[SC_HUMMING].val2
- +sd->sc_data[SC_HUMMING].val3) * sd->hit/100;
- if(sd->sc_data[SC_VIOLENTGALE].timer!=-1 && sd->def_ele==4){ // ƒoƒCƒIƒŒƒ“ƒgƒQƒCƒ‹
- sd->flee += sd->flee*sd->sc_data[SC_VIOLENTGALE].val3/100;
- }
- if(sd->sc_data[SC_BLIND].timer!=-1){ // ˆÃ?
- sd->hit -= sd->hit*25/100;
- sd->flee -= sd->flee*25/100;
- }
- if(sd->sc_data[SC_WINDWALK].timer!=-1) // ƒEƒBƒ“ƒhƒEƒH?ƒN
- sd->flee += sd->flee*(sd->sc_data[SC_WINDWALK].val2)/100;
- if(sd->sc_data[SC_SPIDERWEB].timer!=-1) //ƒXƒpƒCƒ_?ƒEƒFƒu
- sd->flee -= sd->flee*50/100;
- if(sd->sc_data[SC_TRUESIGHT].timer!=-1) //ƒgƒDƒ‹?ƒTƒCƒg
- sd->hit += 3*(sd->sc_data[SC_TRUESIGHT].val1);
- if(sd->sc_data[SC_CONCENTRATION].timer!=-1) //ƒRƒ“ƒZƒ“ƒgƒŒ?ƒVƒ‡ƒ“
- sd->hit += (10*(sd->sc_data[SC_CONCENTRATION].val1));
-
- // ‘Ï«
- if(sd->sc_data[SC_SIEGFRIED].timer!=-1){ // •sŽ€g‚̃W?ƒNƒtƒŠ?ƒh
- sd->subele[1] += sd->sc_data[SC_SIEGFRIED].val2; // …
- sd->subele[2] += sd->sc_data[SC_SIEGFRIED].val2; // …
- sd->subele[3] += sd->sc_data[SC_SIEGFRIED].val2; // ‰Î
- sd->subele[4] += sd->sc_data[SC_SIEGFRIED].val2; // …
- sd->subele[5] += sd->sc_data[SC_SIEGFRIED].val2; // …
- sd->subele[6] += sd->sc_data[SC_SIEGFRIED].val2; // …
- sd->subele[7] += sd->sc_data[SC_SIEGFRIED].val2; // …
- sd->subele[8] += sd->sc_data[SC_SIEGFRIED].val2; // …
- sd->subele[9] += sd->sc_data[SC_SIEGFRIED].val2; // …
- }
- if(sd->sc_data[SC_PROVIDENCE].timer!=-1){ // ƒvƒƒ”ƒBƒfƒ“ƒX
- sd->subele[6] += sd->sc_data[SC_PROVIDENCE].val2; // ? ¹?«
- sd->subrace[6] += sd->sc_data[SC_PROVIDENCE].val2; // ? ?–‚
- }
-
- // ‚»‚Ì‘¼
- if(sd->sc_data[SC_APPLEIDUN].timer!=-1){ // ƒCƒhƒDƒ“‚Ì—ÑŒç
- sd->status.max_hp += ((5+sd->sc_data[SC_APPLEIDUN].val1*2+((sd->sc_data[SC_APPLEIDUN].val2+1)>>1)
- +sd->sc_data[SC_APPLEIDUN].val3/10) * sd->status.max_hp)/100;
- if(sd->status.max_hp < 0 || sd->status.max_hp > battle_config.max_hp)
- sd->status.max_hp = battle_config.max_hp;
- }
- if(sd->sc_data[SC_DELUGE].timer!=-1 && sd->def_ele==1){ // ƒfƒŠƒ…?ƒW
- sd->status.max_hp += sd->status.max_hp*sd->sc_data[SC_DELUGE].val3/100;
- if(sd->status.max_hp < 0 || sd->status.max_hp > battle_config.max_hp)
- sd->status.max_hp = battle_config.max_hp;
- }
- if(sd->sc_data[SC_SERVICE4U].timer!=-1) { // ƒT?ƒrƒXƒtƒH?ƒ†?
- sd->status.max_sp += sd->status.max_sp*(10+sd->sc_data[SC_SERVICE4U].val1+sd->sc_data[SC_SERVICE4U].val2
- +sd->sc_data[SC_SERVICE4U].val3)/100;
- if(sd->status.max_sp < 0 || sd->status.max_sp > battle_config.max_sp)
- sd->status.max_sp = battle_config.max_sp;
- sd->dsprate-=(10+sd->sc_data[SC_SERVICE4U].val1*3+sd->sc_data[SC_SERVICE4U].val2
- +sd->sc_data[SC_SERVICE4U].val3);
- if(sd->dsprate<0)sd->dsprate=0;
- }
-
- if(sd->sc_data[SC_FORTUNE].timer!=-1) // K‰^‚̃LƒX
- sd->critical += (10+sd->sc_data[SC_FORTUNE].val1+sd->sc_data[SC_FORTUNE].val2
- +sd->sc_data[SC_FORTUNE].val3)*10;
-
- if(sd->sc_data[SC_EXPLOSIONSPIRITS].timer!=-1){ // ”š—ô”g“®
- if(s_class.job==23)
- sd->critical += sd->sc_data[SC_EXPLOSIONSPIRITS].val1*100;
- else
- sd->critical += sd->sc_data[SC_EXPLOSIONSPIRITS].val2;
- }
-
- if(sd->sc_data[SC_STEELBODY].timer!=-1){ // ‹à„
- sd->def = 90;
- sd->mdef = 90;
- aspd_rate += 25;
- sd->speed = (sd->speed * 125) / 100;
- }
- if(sd->sc_data[SC_DEFENDER].timer != -1) {
- sd->aspd += (550 - sd->sc_data[SC_DEFENDER].val1*50);
- sd->speed = (sd->speed * (155 - sd->sc_data[SC_DEFENDER].val1*5)) / 100;
- }
- if(sd->sc_data[SC_ENCPOISON].timer != -1)
- sd->addeff[4] += sd->sc_data[SC_ENCPOISON].val2;
-
- if( sd->sc_data[SC_DANCING].timer!=-1 ){ // ‰‰‘t/ƒ_ƒ“ƒXŽg—p’†
- sd->speed*=4;
- sd->nhealsp = 0;
- sd->nshealsp = 0;
- sd->nsshealsp = 0;
- }
- if(sd->sc_data[SC_CURSE].timer!=-1)
- sd->speed += 450;
-
- if(sd->sc_data[SC_TRUESIGHT].timer!=-1) //ƒgƒDƒ‹?ƒTƒCƒg
- sd->critical += sd->critical*(sd->sc_data[SC_TRUESIGHT].val1)/100;
-
-/* if(sd->sc_data[SC_VOLCANO].timer!=-1) // ƒGƒ“ƒ`ƒƒƒ“ƒgƒ|ƒCƒYƒ“(?«‚Íbattle.c‚Å)
- sd->addeff[2]+=sd->sc_data[SC_VOLCANO].val2;//% of granting
- if(sd->sc_data[SC_DELUGE].timer!=-1) // ƒGƒ“ƒ`ƒƒƒ“ƒgƒ|ƒCƒYƒ“(?«‚Íbattle.c‚Å)
- sd->addeff[0]+=sd->sc_data[SC_DELUGE].val2;//% of granting
- */
- if(sd->sc_data[SC_BERSERK].timer!=-1) { //All Def/MDef reduced to 0 while in Berserk [DracoRPG]
- sd->def = sd->def2 = 0;
- sd->mdef = sd->mdef2 = 0;
- sd->flee -= sd->flee*50/100;
- aspd_rate -= 30;
- //sd->base_atk *= 3;
- }
- if(sd->sc_data[SC_KEEPING].timer!=-1)
- sd->def = 100;
- if(sd->sc_data[SC_BARRIER].timer!=-1)
- sd->mdef = 100;
- }
-
- if(sd->speed_rate != 100)
- sd->speed = sd->speed*sd->speed_rate/100;
- if(sd->speed < 1) sd->speed = 1;
- if(aspd_rate != 100)
- sd->aspd = sd->aspd*aspd_rate/100;
- if(pc_isriding(sd)) // ‹R•ºC—û
- sd->aspd = sd->aspd*(100 + 10*(5 - pc_checkskill(sd,KN_CAVALIERMASTERY)))/ 100;
- if(sd->aspd < battle_config.max_aspd) sd->aspd = battle_config.max_aspd;
- sd->amotion = sd->aspd;
- sd->dmotion = 800-sd->paramc[1]*4;
- if(sd->dmotion<400)
- sd->dmotion = 400;
- if(sd->skilltimer != -1 && (skill = pc_checkskill(sd,SA_FREECAST)) > 0) {
- sd->prev_speed = sd->speed;
- sd->speed = sd->speed*(175 - skill*5)/100;
- }
-
- if(sd->status.hp>sd->status.max_hp)
- sd->status.hp=sd->status.max_hp;
- if(sd->status.sp>sd->status.max_sp)
- sd->status.sp=sd->status.max_sp;
-
- if(first&4)
- return 0;
- if(first&3) {
- clif_updatestatus(sd,SP_SPEED);
- clif_updatestatus(sd,SP_MAXHP);
- clif_updatestatus(sd,SP_MAXSP);
- if(first&1) {
- clif_updatestatus(sd,SP_HP);
- clif_updatestatus(sd,SP_SP);
- }
- return 0;
- }
-
- if(b_class != sd->view_class) {
- clif_changelook(&sd->bl,LOOK_BASE,sd->view_class);
-#if PACKETVER < 4
- clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
- clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
-#else
- clif_changelook(&sd->bl,LOOK_WEAPON,0);
-#endif
- }
-
- if( memcmp(b_skill,sd->status.skill,sizeof(sd->status.skill)) || b_attackrange != sd->attackrange)
- clif_skillinfoblock(sd); // ƒXƒLƒ‹‘—M
-
- if(b_speed != sd->speed)
- clif_updatestatus(sd,SP_SPEED);
- if(b_weight != sd->weight)
- clif_updatestatus(sd,SP_WEIGHT);
- if(b_max_weight != sd->max_weight) {
- clif_updatestatus(sd,SP_MAXWEIGHT);
- pc_checkweighticon(sd);
- }
- for(i=0;i<6;i++)
- if(b_paramb[i] + b_parame[i] != sd->paramb[i] + sd->parame[i])
- clif_updatestatus(sd,SP_STR+i);
- if(b_hit != sd->hit)
- clif_updatestatus(sd,SP_HIT);
- if(b_flee != sd->flee)
- clif_updatestatus(sd,SP_FLEE1);
- if(b_aspd != sd->aspd)
- clif_updatestatus(sd,SP_ASPD);
- if(b_watk != sd->watk || b_base_atk != sd->base_atk)
- clif_updatestatus(sd,SP_ATK1);
- if(b_def != sd->def)
- clif_updatestatus(sd,SP_DEF1);
- if(b_watk2 != sd->watk2)
- clif_updatestatus(sd,SP_ATK2);
- if(b_def2 != sd->def2)
- clif_updatestatus(sd,SP_DEF2);
- if(b_flee2 != sd->flee2)
- clif_updatestatus(sd,SP_FLEE2);
- if(b_critical != sd->critical)
- clif_updatestatus(sd,SP_CRITICAL);
- if(b_matk1 != sd->matk1)
- clif_updatestatus(sd,SP_MATK1);
- if(b_matk2 != sd->matk2)
- clif_updatestatus(sd,SP_MATK2);
- if(b_mdef != sd->mdef)
- clif_updatestatus(sd,SP_MDEF1);
- if(b_mdef2 != sd->mdef2)
- clif_updatestatus(sd,SP_MDEF2);
- if(b_attackrange != sd->attackrange)
- clif_updatestatus(sd,SP_ATTACKRANGE);
- if(b_max_hp != sd->status.max_hp)
- clif_updatestatus(sd,SP_MAXHP);
- if(b_max_sp != sd->status.max_sp)
- clif_updatestatus(sd,SP_MAXSP);
- if(b_hp != sd->status.hp)
- clif_updatestatus(sd,SP_HP);
- if(b_sp != sd->status.sp)
- clif_updatestatus(sd,SP_SP);
-
-/* if(before.cart_num != before.cart_num || before.cart_max_num != before.cart_max_num ||
- before.cart_weight != before.cart_weight || before.cart_max_weight != before.cart_max_weight )
- clif_updatestatus(sd,SP_CARTINFO);*/
-
- if(sd->status.hp<sd->status.max_hp>>2 && pc_checkskill(sd,SM_AUTOBERSERK)>0 &&
- (sd->sc_data[SC_PROVOKE].timer==-1 || sd->sc_data[SC_PROVOKE].val2==0 ) && !pc_isdead(sd))
- // ƒI?ƒgƒo?ƒT?ƒN?“®
- skill_status_change_start(&sd->bl,SC_PROVOKE,10,1,0,0,0,0);
-
- return 0;
-}
-
-/*==========================================
- * For quick calculating [Celest]
- *------------------------------------------
- */
-int pc_calcspeed (struct map_session_data *sd)
-{
- int b_speed, skill;
- struct pc_base_job s_class;
-
- nullpo_retr(0, sd);
-
- s_class = pc_calc_base_job(sd->status.class);
-
- b_speed = sd->speed;
- sd->speed = DEFAULT_WALK_SPEED ;
-
- if(sd->sc_count){
- if(sd->sc_data[SC_INCREASEAGI].timer!=-1 && sd->sc_data[SC_QUAGMIRE].timer == -1 && sd->sc_data[SC_DONTFORGETME].timer == -1){ // ‘¬“x?‰Á
- sd->speed -= sd->speed *25/100;
- }
- if(sd->sc_data[SC_DECREASEAGI].timer!=-1) {
- sd->speed = sd->speed *125/100;
- }
- if(sd->sc_data[SC_CLOAKING].timer!=-1) {
- sd->speed = sd->speed * (sd->sc_data[SC_CLOAKING].val3-sd->sc_data[SC_CLOAKING].val1*3) /100;
- }
- if(sd->sc_data[SC_CHASEWALK].timer!=-1) {
- sd->speed = sd->speed * sd->sc_data[SC_CHASEWALK].val3 /100;
- }
- if(sd->sc_data[SC_QUAGMIRE].timer!=-1){
- sd->speed = sd->speed*3/2;
- }
- if(sd->sc_data[SC_WINDWALK].timer!=-1) {
- sd->speed -= sd->speed *(sd->sc_data[SC_WINDWALK].val1*2)/100;
- }
- if(sd->sc_data[SC_CARTBOOST].timer!=-1) {
- sd->speed -= (DEFAULT_WALK_SPEED * 20)/100;
- }
- if(sd->sc_data[SC_BERSERK].timer!=-1) {
- sd->speed -= sd->speed *25/100;
- }
- if(sd->sc_data[SC_WEDDING].timer!=-1) {
- sd->speed = 2*DEFAULT_WALK_SPEED;
- }
- if(sd->sc_data[SC_DONTFORGETME].timer!=-1){
- sd->speed= sd->speed*(100+sd->sc_data[SC_DONTFORGETME].val1*2 + sd->sc_data[SC_DONTFORGETME].val2 + (sd->sc_data[SC_DONTFORGETME].val3&0xffff))/100;
- }
- if(sd->sc_data[SC_STEELBODY].timer!=-1){
- sd->speed = (sd->speed * 125) / 100;
- }
- if(sd->sc_data[SC_DEFENDER].timer != -1) {
- sd->speed = (sd->speed * (155 - sd->sc_data[SC_DEFENDER].val1*5)) / 100;
- }
- if( sd->sc_data[SC_DANCING].timer!=-1 ){
- sd->speed*=4;
- }
- if(sd->sc_data[SC_CURSE].timer!=-1)
- sd->speed += 450;
- }
-
- if(sd->status.option&2 && (skill = pc_checkskill(sd,RG_TUNNELDRIVE))>0 )
- sd->speed += (1.2*DEFAULT_WALK_SPEED - skill*9);
- if (pc_iscarton(sd) && (skill=pc_checkskill(sd,MC_PUSHCART))>0)
- sd->speed += (10-skill) * (DEFAULT_WALK_SPEED * 0.1);
- else if (pc_isriding(sd)) {
- sd->speed -= (0.25 * DEFAULT_WALK_SPEED);
- }
- if((skill=pc_checkskill(sd,TF_MISS))>0)
- if(s_class.job==12)
- sd->speed -= sd->speed *(skill*1.5)/100;
-
- if(sd->speed_rate != 100)
- sd->speed = sd->speed*sd->speed_rate/100;
- if(sd->speed < 1) sd->speed = 1;
-
- if(sd->skilltimer != -1 && (skill = pc_checkskill(sd,SA_FREECAST)) > 0) {
- sd->prev_speed = sd->speed;
- sd->speed = sd->speed*(175 - skill*5)/100;
- }
-
- if(b_speed != sd->speed)
- clif_updatestatus(sd,SP_SPEED);
-
- return 0;
-}
-
-/*==========================================
* ? ”õ•i‚É‚æ‚é”\—Í“™‚̃{?ƒiƒXÝ’è
*------------------------------------------
*/
int pc_bonus(struct map_session_data *sd,int type,int val)
{
+ int i;
nullpo_retr(0, sd);
switch(type){
@@ -2523,20 +1488,12 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
sd->parame[SP_INT-SP_STR]+=val;
sd->parame[SP_DEX-SP_STR]+=val;
sd->parame[SP_LUK-SP_STR]+=val;
- clif_updatestatus(sd,13);
- clif_updatestatus(sd,14);
- clif_updatestatus(sd,15);
- clif_updatestatus(sd,16);
- clif_updatestatus(sd,17);
- clif_updatestatus(sd,18);
}
break;
case SP_AGI_VIT: // [Valaris]
if(sd->state.lr_flag!=2) {
sd->parame[SP_AGI-SP_STR]+=val;
sd->parame[SP_VIT-SP_STR]+=val;
- clif_updatestatus(sd,14);
- clif_updatestatus(sd,15);
}
break;
case SP_AGI_DEX_STR: // [Valaris]
@@ -2544,9 +1501,6 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
sd->parame[SP_AGI-SP_STR]+=val;
sd->parame[SP_DEX-SP_STR]+=val;
sd->parame[SP_STR-SP_STR]+=val;
- clif_updatestatus(sd,14);
- clif_updatestatus(sd,17);
- clif_updatestatus(sd,13);
}
break;
case SP_PERFECT_HIDE: // [Valaris]
@@ -2570,11 +1524,106 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
sd->unbreakable += val;
}
break;
+ case SP_UNBREAKABLE_WEAPON:
+ if(sd->state.lr_flag != 2)
+ sd->unbreakable_equip |= EQP_WEAPON;
+ break;
+ case SP_UNBREAKABLE_ARMOR:
+ if(sd->state.lr_flag != 2)
+ sd->unbreakable_equip |= EQP_ARMOR;
+ break;
+ case SP_UNBREAKABLE_HELM:
+ if(sd->state.lr_flag != 2)
+ sd->unbreakable_equip |= EQP_HELM;
+ break;
+ case SP_UNBREAKABLE_SHIELD:
+ if(sd->state.lr_flag != 2)
+ sd->unbreakable_equip |= EQP_SHIELD;
+ break;
case SP_CLASSCHANGE: // [Valaris]
if(sd->state.lr_flag !=2){
sd->classchange=val;
}
break;
+ case SP_LONG_ATK_RATE:
+ if(sd->status.weapon == 11 && sd->state.lr_flag != 2)
+ sd->atk_rate += val;
+ break;
+ case SP_BREAK_WEAPON_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->break_weapon_rate+=val;
+ break;
+ case SP_BREAK_ARMOR_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->break_armor_rate+=val;
+ break;
+ case SP_ADD_STEAL_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->add_steal_rate+=val;
+ break;
+ case SP_DELAYRATE:
+ if(sd->state.lr_flag != 2)
+ sd->delayrate+=val;
+ break;
+ case SP_CRIT_ATK_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->crit_atk_rate += val;
+ break;
+ case SP_NO_REGEN:
+ if(sd->state.lr_flag != 2)
+ sd->no_regen = val;
+ break;
+ case SP_UNSTRIPABLE_WEAPON:
+ if(sd->state.lr_flag != 2)
+ sd->unstripable_equip |= EQP_WEAPON;
+ break;
+ case SP_UNSTRIPABLE:
+ case SP_UNSTRIPABLE_ARMOR:
+ if(sd->state.lr_flag != 2)
+ sd->unstripable_equip |= EQP_ARMOR;
+ break;
+ case SP_UNSTRIPABLE_HELM:
+ if(sd->state.lr_flag != 2)
+ sd->unstripable_equip |= EQP_HELM;
+ break;
+ case SP_UNSTRIPABLE_SHIELD:
+ if(sd->state.lr_flag != 2)
+ sd->unstripable_equip |= EQP_SHIELD;
+ break;
+ case SP_SP_GAIN_VALUE:
+ if(!sd->state.lr_flag)
+ sd->sp_gain_value += val;
+ break;
+ case SP_IGNORE_DEF_MOB: // 0:normal monsters only, 1:affects boss monsters as well
+ if(!sd->state.lr_flag)
+ sd->ignore_def_mob |= 1<<val;
+ else if(sd->state.lr_flag == 1)
+ sd->ignore_def_mob_ |= 1<<val;
+ break;
+ case SP_HP_GAIN_VALUE:
+ if(!sd->state.lr_flag)
+ sd->hp_gain_value += val;
+ break;
+ case SP_DAMAGE_WHEN_UNEQUIP:
+ if(!sd->state.lr_flag) {
+ for (i=0; i<11; i++) {
+ if (sd->inventory_data[current_equip_item_index]->equip & equip_pos[i]) {
+ sd->unequip_losehp[i] += val;
+ break;
+ }
+ }
+ }
+ break;
+ case SP_LOSESP_WHEN_UNEQUIP:
+ if(!sd->state.lr_flag) {
+ for (i=0; i<11; i++) {
+ if (sd->inventory_data[current_equip_item_index]->equip & equip_pos[i]) {
+ sd->unequip_losesp[i] += val;
+ break;
+ }
+ }
+ }
+ break;
default:
if(battle_config.error_log)
printf("pc_bonus: unknown type %d %d !\n",type,val);
@@ -2754,8 +1803,9 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
}
else if(sd->state.lr_flag == 1) {
sd->sp_drain_rate_ += type2;
- sd->sp_drain_per_ += val;
+ sd->sp_drain_per_ += val;
}
+ sd->sp_drain_type = 0;
break;
case SP_SP_DRAIN_VALUE:
if(!sd->state.lr_flag) {
@@ -2766,7 +1816,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
sd->sp_drain_rate_ += type2;
sd->sp_drain_value_ += val;
}
-
+ sd->sp_drain_type = 0;
break;
case SP_WEAPON_COMA_ELE:
if(sd->state.lr_flag != 2)
@@ -2780,8 +1830,92 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
if(sd->state.lr_flag !=2){
sd->random_attack_increase_add = type2;
sd->random_attack_increase_per += val;
- }
+ }
+ break;
+ case SP_WEAPON_ATK:
+ if(sd->state.lr_flag != 2)
+ sd->weapon_atk[type2]+=val;
+ break;
+ case SP_WEAPON_ATK_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->weapon_atk_rate[type2]+=val;
+ break;
+ case SP_CRITICAL_ADDRACE:
+ if(sd->state.lr_flag != 2)
+ sd->critaddrace[type2]+=val;
+ break;
+ case SP_ADDEFF_WHENHIT:
+ if(sd->state.lr_flag != 2) {
+ sd->addeff3[type2]+=val;
+ sd->addeff3_type[type2]=1;
+ }
break;
+ case SP_ADDEFF_WHENHIT_SHORT:
+ if(sd->state.lr_flag != 2) {
+ sd->addeff3[type2]+=val;
+ sd->addeff3_type[type2]=0;
+ }
+ break;
+ case SP_SKILL_ATK:
+ if(sd->state.lr_flag != 2) {
+ if (sd->skillatk[0] == type2)
+ sd->skillatk[1] += val;
+ else {
+ sd->skillatk[0] = type2;
+ sd->skillatk[1] = val;
+ }
+ }
+ break;
+ case SP_ADD_DAMAGE_BY_CLASS:
+ if(sd->state.lr_flag != 2) {
+ for(i=0;i<sd->add_damage_class_count2;i++) {
+ if(sd->add_damage_classid2[i] == type2) {
+ sd->add_damage_classrate2[i] += val;
+ break;
+ }
+ }
+ if(i >= sd->add_damage_class_count2 && sd->add_damage_class_count2 < 10) {
+ sd->add_damage_classid2[sd->add_damage_class_count2] = type2;
+ sd->add_damage_classrate2[sd->add_damage_class_count2] += val;
+ sd->add_damage_class_count2++;
+ }
+ }
+ break;
+ case SP_HP_LOSS_RATE:
+ if(sd->state.lr_flag != 2) {
+ sd->hp_loss_value = type2;
+ sd->hp_loss_rate = val;
+ }
+ break;
+ case SP_ADDRACE2:
+ if (type2 > 0 && type2 < MAX_MOB_RACE_DB)
+ break;
+ if(sd->state.lr_flag != 2)
+ sd->addrace2[type2] += val;
+ else
+ sd->addrace2_[type2] += val;
+ break;
+ case SP_SUBSIZE:
+ if(sd->state.lr_flag != 2)
+ sd->subsize[type2]+=val;
+ break;
+ case SP_SUBRACE2:
+ if(sd->state.lr_flag != 2)
+ sd->subrace2[type2]+=val;
+ break;
+ case SP_ADD_ITEM_HEAL_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->itemhealrate[type2 - 1] += val;
+ break;
+ case SP_EXP_ADDRACE:
+ if(sd->state.lr_flag != 2)
+ sd->expaddrace[type2]+=val;
+ break;
+ case SP_SP_GAIN_RACE:
+ if(sd->state.lr_flag != 2)
+ sd->sp_gain_race[type2]+=val;
+ break;
+
default:
if(battle_config.error_log)
printf("pc_bonus2: unknown type %d %d %d!\n",type,type2,val);
@@ -2819,6 +1953,42 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
sd->autospell_rate = val;
}
break;
+ case SP_AUTOSPELL_WHENHIT:
+ if(sd->state.lr_flag != 2){
+ sd->autospell2_id = type2;
+ sd->autospell2_lv = type3;
+ sd->autospell2_rate = val;
+ sd->autospell2_type = 1; // enemy
+ }
+ break;
+ case SP_HP_LOSS_RATE:
+ if(sd->state.lr_flag != 2) {
+ sd->hp_loss_value = type2;
+ sd->hp_loss_rate = type3;
+ sd->hp_loss_type = val;
+ }
+ break;
+ case SP_SP_DRAIN_RATE:
+ if(!sd->state.lr_flag) {
+ sd->sp_drain_rate += type2;
+ sd->sp_drain_per += type3;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->sp_drain_rate_ += type2;
+ sd->sp_drain_per_ += type3;
+ }
+ sd->sp_drain_type = val;
+ break;
+ case SP_SP_DRAIN_VALUE:
+ if(!sd->state.lr_flag) {
+ sd->sp_drain_rate += type2;
+ sd->sp_drain_value += type3;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->sp_drain_rate_ += type2;
+ sd->sp_drain_value_ += type3;
+ }
+ sd->sp_drain_type = val;
default:
if(battle_config.error_log)
printf("pc_bonus3: unknown type %d %d %d %d!\n",type,type2,type3,val);
@@ -2828,6 +1998,26 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
return 0;
}
+int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4,int val)
+{
+ switch(type){
+ case SP_AUTOSPELL_WHENHIT:
+ if(sd->state.lr_flag != 2){
+ sd->autospell2_id = type2;
+ sd->autospell2_lv = type3;
+ sd->autospell2_rate = type4;
+ sd->autospell2_type = val; // 0: self, 1: enemy
+ }
+ break;
+ default:
+ if(battle_config.error_log)
+ printf("pc_bonus4: unknown type %d %d %d %d %d!\n",type,type2,type3,type4,val);
+ break;
+ }
+
+ return 0;
+}
+
/*==========================================
* ƒXƒNƒŠƒvƒg‚É‚æ‚éƒXƒLƒ‹Š“¾
*------------------------------------------
@@ -2843,12 +2033,12 @@ int pc_skill(struct map_session_data *sd,int id,int level,int flag)
}
if(!flag && (sd->status.skill[id].id == id || level == 0)){ // ƒNƒGƒXƒgŠ“¾‚Ȃ炱‚±‚Å?Œ‚ðŠm”F‚µ‚Ä‘—M‚·‚é
sd->status.skill[id].lv=level;
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
clif_skillinfoblock(sd);
}
else if(flag==2 && (sd->status.skill[id].id == id || level == 0)){ // ƒNƒGƒXƒgŠ“¾‚Ȃ炱‚±‚Å?Œ‚ðŠm”F‚µ‚Ä‘—M‚·‚é
sd->status.skill[id].lv+=level;
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
clif_skillinfoblock(sd);
}
else if(sd->status.skill[id].lv < level){ // ?‚¦‚ç‚ê‚邪lv‚ª¬‚³‚¢‚È‚ç
@@ -2865,6 +2055,32 @@ int pc_skill(struct map_session_data *sd,int id,int level,int flag)
}
/*==========================================
+ *
+ *------------------------------------------
+ */
+int pc_blockskill_end(int tid,unsigned int tick,int id,int data)
+{
+ struct map_session_data *sd = map_id2sd(id);
+ if (data <= 0 || data >= MAX_SKILL)
+ return 0;
+ if (sd) sd->blockskill[data] = 0;
+
+ return 1;
+}
+int pc_blockskill_start (struct map_session_data *sd, int skillid, int tick)
+{
+ nullpo_retr (-1, sd);
+
+ if (skillid >= 10000 && skillid < 10015)
+ skillid -= 9500;
+ else if (skillid < 1 || skillid > MAX_SKILL)
+ return -1;
+
+ sd->blockskill[skillid] = 1;
+ return add_timer(gettick()+tick,pc_blockskill_end,sd->bl.id,skillid);
+}
+
+/*==========================================
* ƒJ?ƒh?“ü
*------------------------------------------
*/
@@ -2950,7 +2166,7 @@ int pc_modifysellvalue(struct map_session_data *sd,int orig_value)
}
/*==========================================
- * ƒAƒCƒeƒ€‚𔃂Á‚½Žž‚ÉAV‚µ‚¢ƒAƒCƒeƒ€—“‚ðŽg‚¤‚©A
+ * ƒAƒCƒeƒ€‚𔃂Á‚½ŽbÉAV‚µ‚¢ƒAƒCƒeƒ€—“‚ðŽg‚¤‚©A
* 3–œŒÂ§ŒÀ‚É‚©‚©‚é‚©Šm”F
*------------------------------------------
*/
@@ -3074,7 +2290,7 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount)
i = MAX_INVENTORY;
if(!itemdb_isequip2(data)){
- // ? ”õ•i‚ł͂Ȃ¢‚Ì‚ÅA?Š—L•i‚È‚çŒÂ?‚Ì‚Ý?‰»‚³‚¹‚é
+ // ‘• ”õ•i‚ł͂Ȃ¢‚Ì‚ÅAŠùŠ—L•i‚È‚çŒÂ”‚̂ݕω»‚³‚¹‚é
for(i=0;i<MAX_INVENTORY;i++)
if(sd->status.inventory[i].nameid == item_data->nameid &&
sd->status.inventory[i].card[0] == item_data->card[0] && sd->status.inventory[i].card[1] == item_data->card[1] &&
@@ -3087,7 +2303,7 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount)
}
}
if(i >= MAX_INVENTORY){
- // ? ”õ•i‚©–¢Š—L•i‚¾‚Á‚½‚̂ŋ󂫗“‚֒ljÁ
+ // ‘• ”õ•i‚©–¢Š—L•i‚¾‚Á‚½‚̂ŋ󂫗“‚֒ljÁ
i = pc_search_inventory(sd,0);
if(i >= 0) {
memcpy(&sd->status.inventory[i],item_data,sizeof(sd->status.inventory[0]));
@@ -3118,7 +2334,7 @@ int pc_delitem(struct map_session_data *sd,int n,int amount,int type)
sd->weight -= sd->inventory_data[n]->weight*amount ;
if(sd->status.inventory[n].amount<=0){
if(sd->status.inventory[n].equip)
- pc_unequipitem(sd,n,0,BF_NORMAL);
+ pc_unequipitem(sd,n,3);
memset(&sd->status.inventory[n],0,sizeof(sd->status.inventory[0]));
sd->inventory_data[n] = NULL;
}
@@ -3139,19 +2355,17 @@ int pc_dropitem(struct map_session_data *sd,int n,int amount)
nullpo_retr(1, sd);
if(n < 0 || n >= MAX_INVENTORY)
-
return 1;
-
if(amount <= 0)
-
return 1;
-
if (sd->status.inventory[n].nameid <= 0 ||
sd->status.inventory[n].amount < amount ||
sd->trade_partner != 0 || sd->vender_id != 0 ||
- sd->status.inventory[n].amount <= 0)
+ sd->status.inventory[n].amount <= 0 ||
+ itemdb_isdropable(sd->status.inventory[n].nameid) == 0 || // Celest
+ pc_candrop(sd,sd->status.inventory[n].nameid))
return 1;
map_addflooritem(&sd->status.inventory[n], amount, sd->bl.m, sd->bl.x, sd->bl.y, NULL, NULL, NULL, 0);
pc_delitem(sd, n, amount, 0);
@@ -3227,6 +2441,8 @@ int pc_isUseitem(struct map_session_data *sd,int n)
if(item == NULL)
return 0;
+ if(item->type != 0 && item->type != 2)
+ return 0;
if((nameid == 605) && map[sd->bl.m].flag.gvg)
return 0;
if(nameid == 601 && (map[sd->bl.m].flag.noteleport || map[sd->bl.m].flag.gvg)) {
@@ -3241,18 +2457,16 @@ int pc_isUseitem(struct map_session_data *sd,int n)
return 0;
if(item->elv > 0 && sd->status.base_level < item->elv)
return 0;
- if(((sd->status.class==13 || sd->status.class==4014) && ((1<<7)&item->class) == 0) || // have mounted classes use unmounted items [Valaris]
- ((sd->status.class==21 || sd->status.class==4022) && ((1<<14)&item->class) == 0))
+ if(((sd->status.class_==13 || sd->status.class_==4014) && ((1<<7)&item->class_) == 0) || // have mounted classes use unmounted items [Valaris]
+ ((sd->status.class_==21 || sd->status.class_==4022) && ((1<<14)&item->class_) == 0))
return 0;
- if(sd->status.class!=13 && sd->status.class!=4014 && sd->status.class!=21 && sd->status.class!=4022)
- if((sd->status.class<=4000 && ((1<<sd->status.class)&item->class) == 0) || (sd->status.class>4000 && sd->status.class<4023 && ((1<<(sd->status.class-4001))&item->class) == 0) ||
- (sd->status.class>=4023 && ((1<<(sd->status.class-4023))&item->class) == 0))
+ if(sd->status.class_!=13 && sd->status.class_!=4014 && sd->status.class_!=21 && sd->status.class_!=4022)
+ if((sd->status.class_<=4000 && ((1<<sd->status.class_)&item->class_) == 0) || (sd->status.class_>4000 && sd->status.class_<4023 && ((1<<(sd->status.class_-4001))&item->class_) == 0) ||
+ (sd->status.class_>=4023 && ((1<<(sd->status.class_-4023))&item->class_) == 0))
return 0;
-#ifndef TXT_ONLY
if((log_config.branch > 0) && (nameid == 604))
log_branch(sd);
-#endif
return 1;
}
@@ -3263,28 +2477,31 @@ int pc_isUseitem(struct map_session_data *sd,int n)
*/
int pc_useitem(struct map_session_data *sd,int n)
{
- int nameid,amount;
+ int amount;
nullpo_retr(1, sd);
if(n >=0 && n < MAX_INVENTORY) {
- nameid = sd->status.inventory[n].nameid;
+ char *script;
+ sd->itemid = sd->status.inventory[n].nameid;
amount = sd->status.inventory[n].amount;
if(sd->status.inventory[n].nameid <= 0 ||
sd->status.inventory[n].amount <= 0 ||
sd->sc_data[SC_BERSERK].timer!=-1 ||
sd->sc_data[SC_MARIONETTE].timer!=-1 ||
+ (pc_issit(sd) && (sd->itemid == 605 || sd->itemid == 606)) ||
+ //added item_noequip.txt items check by Maya&[Lupus]
+ (map[sd->bl.m].flag.pvp && (sd->inventory_data[n]->flag.no_equip&1) ) || // PVP
+ (map[sd->bl.m].flag.gvg && (sd->inventory_data[n]->flag.no_equip>1) ) || // GVG
!pc_isUseitem(sd,n) ) {
clif_useitemack(sd,n,0,0);
return 1;
}
- if(sd->inventory_data[n])
- run_script(sd->inventory_data[n]->use_script,0,sd->bl.id,0);
-
- pc_delitem(sd,n,1,1);
+ script = sd->inventory_data[n]->use_script;
amount = sd->status.inventory[n].amount;
-
- clif_useitemack(sd,n,amount,1);
+ clif_useitemack(sd,n,amount-1,1);
+ run_script(script,0,sd->bl.id,0);
+ pc_delitem(sd,n,1,1);
}
return 0;
@@ -3311,7 +2528,7 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun
i=MAX_CART;
if(!itemdb_isequip2(data)){
- // ? ”õ•i‚ł͂Ȃ¢‚Ì‚ÅA?Š—L•i‚È‚çŒÂ?‚Ì‚Ý?‰»‚³‚¹‚é
+ // ‘• ”õ•i‚ł͂Ȃ¢‚Ì‚ÅAŠùŠ—L•i‚È‚çŒÂ”‚̂ݕω»‚³‚¹‚é
for(i=0;i<MAX_CART;i++){
if(sd->status.cart[i].nameid==item_data->nameid &&
sd->status.cart[i].card[0] == item_data->card[0] && sd->status.cart[i].card[1] == item_data->card[1] &&
@@ -3325,7 +2542,7 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun
}
}
if(i >= MAX_CART){
- // ? ”õ•i‚©–¢Š—L•i‚¾‚Á‚½‚̂ŋ󂫗“‚֒ljÁ
+ // ‘• ”õ•i‚©–¢Š—L•i‚¾‚Á‚½‚̂ŋ󂫗“‚֒ljÁ
for(i=0;i<MAX_CART;i++){
if(sd->status.cart[i].nameid==0){
memcpy(&sd->status.cart[i],item_data,sizeof(sd->status.cart[0]));
@@ -3380,6 +2597,10 @@ int pc_putitemtocart(struct map_session_data *sd,int idx,int amount) {
nullpo_retr(0, sd);
nullpo_retr(0, item_data = &sd->status.inventory[idx]);
+ if(itemdb_isdropable(sd->status.inventory[idx].nameid) == 0)
+ return 1;
+ if(pc_candrop(sd,sd->status.inventory[idx].nameid)==1)
+ return 1;
if (item_data->nameid==0 || item_data->amount<amount || sd->vender_id)
return 1;
if (pc_cart_additem(sd,item_data,amount) == 0)
@@ -3460,18 +2681,31 @@ int pc_item_identify(struct map_session_data *sd,int idx)
*/
int pc_item_repair(struct map_session_data *sd,int idx)
{
- int flag=1;
+ int flag=1, material;
+ int materials[5] = { 0, 1002, 998, 999, 756 };
+ struct item *item;
nullpo_retr(0, sd);
+ item = &sd->status.inventory[idx];
+
if(idx >= 0 && idx < MAX_INVENTORY) {
- if(sd->status.inventory[idx].nameid > 0 && sd->status.inventory[idx].attribute == 1 ) {
+ if(item->nameid > 0 && item->attribute == 1 ) {
+ if (itemdb_type(item->nameid)==4)
+ material = materials [itemdb_wlv (item->nameid)];
+ else
+ material = materials [3];
+
+ if (pc_search_inventory(sd, material) < 0 ) { //fixed by Lupus (item pos can be = 0!)
+ clif_skill_fail(sd,sd->skillid,0,0);
+ return 0;
+ }
flag=0;
- sd->status.inventory[idx].attribute=0;
+ item->attribute=0;
//Temporary Weapon Repair code [DracoRPG]
- pc_delitem(sd, pc_search_inventory(sd, 999), 1, 0);
+ pc_delitem(sd, pc_search_inventory(sd, material), 1, 0);
clif_equiplist(sd);
- clif_produceeffect(sd, 0, sd->status.inventory[idx].nameid);
+ clif_produceeffect(sd, 0, item->nameid);
clif_misceffect(&sd->bl, 3);
clif_displaymessage(sd->fd,"Item has been repaired.");
}
@@ -3486,63 +2720,49 @@ int pc_item_repair(struct map_session_data *sd,int idx)
*/
int pc_item_refine(struct map_session_data *sd,int idx)
{
- int flag = 1, i = 0, count = 0, ep = 0, per, refine;
+ int flag = 1, i = 0, ep = 0, per;
int material[5] = { 0, 1010, 1011, 984, 984 };
-
+ struct item *item;
+
nullpo_retr(0, sd);
- struct item *item = &sd->status.inventory[idx];
+ item = &sd->status.inventory[idx];
if(idx >= 0 && idx < MAX_INVENTORY) {
if(item->nameid > 0 && itemdb_type(item->nameid)==4) {
// if it's no longer refineable
- if (item->refine == 10) {
+ if (item->refine >= sd->skilllv || item->refine == 10) {
clif_skill_fail(sd,sd->skillid,0,0);
return 0;
}
- refine = item->refine + sd->skilllv > 10
- ? 10 - item->refine : sd->skilllv;
- for (i=0; i < MAX_INVENTORY; i++)
- if(sd->status.inventory[i].nameid == material [itemdb_wlv (item->nameid)])
- count += sd->status.inventory[i].amount;
- if (count < refine ) {
+ if ((i=pc_search_inventory(sd, material [itemdb_wlv (item->nameid)])) < 0 ) { //fixed by Lupus (item pos can be = 0!)
clif_skill_fail(sd,sd->skillid,0,0);
return 0;
}
- per = percentrefinery [itemdb_wlv (item->nameid)][item->refine + refine - 1];
+
+ per = percentrefinery [itemdb_wlv (item->nameid)][(int)item->refine];
//per += pc_checkskill(sd,BS_WEAPONRESEARCH);
per *= (75 + sd->status.job_level/2)/100;
-
+
if (per > rand() % 100) {
flag = 0;
- item->refine += refine;
-
- for (i=0; i < MAX_INVENTORY; i++)
- if(sd->status.inventory[i].nameid == material [itemdb_wlv (item->nameid)]) {
- if (sd->status.inventory[i].amount >= refine) {
- pc_delitem(sd,i,refine,0);
- break;
- } else {
- refine -= sd->status.inventory[i].amount;
- pc_delitem(sd,i,sd->status.inventory[i].amount,0);
- }
- }
-
+ item->refine++;
+ pc_delitem(sd, i, 1, 0);
if(item->equip) {
ep = item->equip;
- pc_unequipitem(sd,idx,0, BF_NORMAL);
+ pc_unequipitem(sd,idx,3);
}
clif_refine(sd->fd,sd,0,idx,item->refine);
- clif_delitem(sd,idx,1);
+ clif_delitem(sd,idx,1);
clif_additem(sd,idx,1,0);
if (ep)
pc_equipitem(sd,idx,ep);
clif_misceffect(&sd->bl,3);
}
else {
- clif_delitem(sd,i,refine);
+ pc_delitem(sd, i, 1, 0);
item->refine = 0;
if(item->equip)
- pc_unequipitem(sd,idx,0, BF_NORMAL);
+ pc_unequipitem(sd,idx,3);
clif_refine(sd->fd,sd,1,idx,item->refine);
pc_delitem(sd,idx,1,0);
clif_misceffect(&sd->bl,2);
@@ -3596,28 +2816,29 @@ int pc_show_steal(struct block_list *bl,va_list ap)
int pc_steal_item(struct map_session_data *sd,struct block_list *bl)
{
if(sd != NULL && bl != NULL && bl->type == BL_MOB) {
- int i,skill,rate,itemid,flag, count;
+ int i,skill,itemid,flag, count;
struct mob_data *md;
md=(struct mob_data *)bl;
- if(!md->state.steal_flag && mob_db[md->class].mexp <= 0 && !(mob_db[md->class].mode&0x20) && md->sc_data[SC_STONE].timer == -1 && md->sc_data[SC_FREEZE].timer == -1 &&
- (!(md->class>1324 && md->class<1364))) // prevent stealing from treasure boxes [Valaris]
+ if(!md->state.steal_flag && mob_db[md->class_].mexp <= 0 && !(mob_db[md->class_].mode&0x20) &&
+ (!(md->class_>1324 && md->class_<1364))) // prevent stealing from treasure boxes [Valaris]
{
+ if (md->sc_data && (md->sc_data[SC_STONE].timer != -1 || md->sc_data[SC_FREEZE].timer != -1))
+ return 0;
skill = battle_config.skill_steal_type == 1
- ? (sd->paramc[4] - mob_db[md->class].dex)/2 + pc_checkskill(sd,TF_STEAL)*6 + 10
- : sd->paramc[4] - mob_db[md->class].dex + pc_checkskill(sd,TF_STEAL)*3 + 10;
+ ? (sd->paramc[4] - mob_db[md->class_].dex)/2 + pc_checkskill(sd,TF_STEAL)*6 + 10
+ : sd->paramc[4] - mob_db[md->class_].dex + pc_checkskill(sd,TF_STEAL)*3 + 10;
if(0 < skill)
{
- for(count = 8; count <= 8 && count != 0; count--)
+ for(count = 10; count <= 10 && count != 0; count--) //8 -> 10 Lupus
{
- i = rand()%8;
- itemid = mob_db[md->class].dropitem[i].nameid;
+ i = rand()%10; //8 -> 10 Lupus
+ itemid = mob_db[md->class_].dropitem[i].nameid;
if(itemid > 0 && itemdb_type(itemid) != 6)
{
- rate = (mob_db[md->class].dropitem[i].p / battle_config.item_rate_common * 100 * skill)/100;
-
- if(rand()%10000 < rate)
+ //fixed rate. From Freya [Lupus]
+ if (rand() % 10000 < ((mob_db[md->class_].dropitem[i].p * skill) / 100 + sd->add_steal_rate))
{
struct item tmp_item;
memset(&tmp_item,0,sizeof(tmp_item));
@@ -3659,11 +2880,13 @@ int pc_steal_coin(struct map_session_data *sd,struct block_list *bl)
if(sd != NULL && bl != NULL && bl->type == BL_MOB) {
int rate,skill;
struct mob_data *md=(struct mob_data *)bl;
- if(md && !md->state.steal_coin_flag && md->sc_data && md->sc_data[SC_STONE].timer == -1 && md->sc_data[SC_FREEZE].timer == -1) {
+ if(md && !md->state.steal_coin_flag) {
+ if (md->sc_data && (md->sc_data[SC_STONE].timer != -1 || md->sc_data[SC_FREEZE].timer != -1))
+ return 0;
skill = pc_checkskill(sd,RG_STEALCOIN)*10;
- rate = skill + (sd->status.base_level - mob_db[md->class].lv)*3 + sd->paramc[4]*2 + sd->paramc[5]*2;
+ rate = skill + (sd->status.base_level - mob_db[md->class_].lv)*3 + sd->paramc[4]*2 + sd->paramc[5]*2;
if(rand()%1000 < rate) {
- pc_getzeny(sd,mob_db[md->class].lv*10 + rand()%100);
+ pc_getzeny(sd,mob_db[md->class_].lv*10 + rand()%100);
md->state.steal_coin_flag = 1;
return 1;
}
@@ -3682,7 +2905,7 @@ int pc_steal_coin(struct map_session_data *sd,struct block_list *bl)
int pc_setpos(struct map_session_data *sd,char *mapname_org,int x,int y,int clrtype)
{
char mapname[24];
- int m=0,c=0,disguise=0;
+ int m=0,disguise=0;
nullpo_retr(0, sd);
@@ -3711,43 +2934,58 @@ int pc_setpos(struct map_session_data *sd,char *mapname_org,int x,int y,int clrt
skill_gangsterparadise(sd,0);
}
- if(sd->sc_data[SC_TRICKDEAD].timer != -1)
- skill_status_change_end(&sd->bl, SC_TRICKDEAD, -1);
+ if (sd->sc_count) {
+ if(sd->sc_data[SC_TRICKDEAD].timer != -1)
+ status_change_end(&sd->bl, SC_TRICKDEAD, -1);
+ if(sd->sc_data[SC_BLADESTOP].timer!=-1)
+ status_change_end(&sd->bl,SC_BLADESTOP,-1);
+ if(sd->sc_data[SC_DANCING].timer!=-1) // clear dance effect when warping [Valaris]
+ skill_stop_dancing(&sd->bl,0);
+ if (sd->sc_data[SC_BASILICA].timer!=-1) {
+ /*int i;
+ for (i=0;i<MAX_SKILLUNITGROUP;i++)
+ if (sd->skillunit[i].skill_id==HP_BASILICA)
+ skill_delunitgroup(&sd->skillunit[i]);*/
+
+ struct skill_unit_group *sg = (struct skill_unit_group *)sd->sc_data[SC_BASILICA].val4;
+ if (sg && sg->src_id == sd->bl.id)
+ skill_delunitgroup (sg);
+ status_change_end(&sd->bl,SC_BASILICA,-1);
+ }
+ }
+
if(sd->status.option&2)
- skill_status_change_end(&sd->bl, SC_HIDING, -1);
+ status_change_end(&sd->bl, SC_HIDING, -1);
if(sd->status.option&4)
- skill_status_change_end(&sd->bl, SC_CLOAKING, -1);
- if(sd->status.option&16386)
- skill_status_change_end(&sd->bl, SC_CHASEWALK, -1);
- if(sd->sc_data[SC_BLADESTOP].timer!=-1)
- skill_status_change_end(&sd->bl,SC_BLADESTOP,-1);
- if(sd->sc_data[SC_DANCING].timer!=-1) // clear dance effect when warping [Valaris]
- skill_stop_dancing(&sd->bl,0);
+ status_change_end(&sd->bl, SC_CLOAKING, -1);
+ if(sd->status.option&16384)
+ status_change_end(&sd->bl, SC_CHASEWALK, -1);
if(sd->status.pet_id > 0 && sd->pd && sd->pet.intimate > 0) {
pet_stopattack(sd->pd);
pet_changestate(sd->pd,MS_IDLE,0);
}
-
+
if(sd->disguise) { // clear disguises when warping [Valaris]
clif_clearchar(&sd->bl, 9);
disguise=sd->disguise;
sd->disguise=0;
}
- memcpy(mapname,mapname_org,24);
+ strncpy(mapname,mapname_org,sizeof(mapname));
mapname[16]=0;
- if(strstr(mapname,".gat")==NULL && strlen(mapname)<16){
+ if(strstr(mapname,".gat")==NULL && strstr(mapname,".afm")==NULL && strlen(mapname)<16){
strcat(mapname,".gat");
}
m=map_mapname2mapid(mapname);
+
if(m<0){
if(sd->mapname[0]){
int ip,port;
if(map_mapname2ipport(mapname,&ip,&port)==0){
skill_stop_dancing(&sd->bl,1);
- skill_unit_out_all(&sd->bl,gettick(),1);
+ skill_unit_move(&sd->bl,gettick(),0);
clif_clearchar_area(&sd->bl,clrtype&0xffff);
skill_gangsterparadise(sd,0);
map_delblock(&sd->bl);
@@ -3759,7 +2997,7 @@ int pc_setpos(struct map_session_data *sd,char *mapname_org,int x,int y,int clrt
sd->pd = NULL;
sd->petDB = NULL;
if(battle_config.pet_status_support)
- pc_calcstatus(sd,2);
+ status_calc_pc(sd,2);
}
else if(sd->pet.intimate > 0) {
pet_stopattack(sd->pd);
@@ -3772,11 +3010,13 @@ int pc_setpos(struct map_session_data *sd,char *mapname_org,int x,int y,int clrt
sd->bl.x=x;
sd->bl.y=y;
sd->state.waitingdisconnect=1;
+ pc_clean_skilltree(sd);
pc_makesavestatus(sd);
if(sd->status.pet_id > 0 && sd->pd)
intif_save_petdata(sd->status.account_id,&sd->pet);
chrif_save(sd);
storage_storage_save(sd);
+ storage_delete(sd->status.account_id);
chrif_changemapserver(sd, mapname, x, y, ip, port);
return 0;
}
@@ -3790,7 +3030,7 @@ int pc_setpos(struct map_session_data *sd,char *mapname_org,int x,int y,int clrt
if(x <0 || x >= map[m].xs || y <0 || y >= map[m].ys)
x=y=0;
- if((x==0 && y==0) || (c=read_gat(m,x,y))==1 || c==5){
+ if((x==0 && y==0) || map_getcell(m,x,y,CELL_CHKNOPASS)){
if(x||y) {
if(battle_config.error_log)
printf("stacked (%d,%d)\n",x,y);
@@ -3798,11 +3038,11 @@ int pc_setpos(struct map_session_data *sd,char *mapname_org,int x,int y,int clrt
do {
x=rand()%(map[m].xs-2)+1;
y=rand()%(map[m].ys-2)+1;
- } while((c=read_gat(m,x,y))==1 || c==5);
+ } while(map_getcell(m,x,y,CELL_CHKNOPASS));
}
if(sd->mapname[0] && sd->bl.prev != NULL){
- skill_unit_out_all(&sd->bl,gettick(),1);
+ skill_unit_move(&sd->bl,gettick(),0);
clif_clearchar_area(&sd->bl,clrtype&0xffff);
skill_gangsterparadise(sd,0);
map_delblock(&sd->bl);
@@ -3815,7 +3055,8 @@ int pc_setpos(struct map_session_data *sd,char *mapname_org,int x,int y,int clrt
sd->pd = NULL;
sd->petDB = NULL;
if(battle_config.pet_status_support)
- pc_calcstatus(sd,2);
+ status_calc_pc(sd,2);
+ pc_clean_skilltree(sd);
pc_makesavestatus(sd);
chrif_save(sd);
storage_storage_save(sd);
@@ -3832,13 +3073,13 @@ int pc_setpos(struct map_session_data *sd,char *mapname_org,int x,int y,int clrt
if(disguise) // disguise teleport fix [Valaris]
sd->disguise=disguise;
-
+
memcpy(sd->mapname,mapname,24);
sd->bl.m = m;
sd->to_x = x;
sd->to_y = y;
- // moved and changed dance effect stopping
+ // moved and changed dance effect stopping
sd->bl.x = x;
sd->bl.y = y;
@@ -3861,7 +3102,7 @@ int pc_setpos(struct map_session_data *sd,char *mapname_org,int x,int y,int clrt
*------------------------------------------
*/
int pc_randomwarp(struct map_session_data *sd, int type) {
- int x,y,c,i=0;
+ int x,y,i=0;
int m;
nullpo_retr(0, sd);
@@ -3874,7 +3115,7 @@ int pc_randomwarp(struct map_session_data *sd, int type) {
do{
x=rand()%(map[m].xs-2)+1;
y=rand()%(map[m].ys-2)+1;
- } while (((c=read_gat(m,x,y)) == 1 || c == 5) && (i++) < 1000);
+ }while(map_getcell(m,x,y,CELL_CHKNOPASS) && (i++)<1000 );
if (i < 1000)
pc_setpos(sd,map[m].name,x,y,type);
@@ -3957,7 +3198,7 @@ int pc_can_reach(struct map_session_data *sd,int x,int y)
// ? s•¨
//
/*==========================================
- * ŽŸ‚Ì1?‚É‚©‚©‚鎞ŠÔ‚ðŒvŽZ
+ * ŽŸ‚Ì1?‚É‚©‚©‚éŽjÔ‚ðŒvŽZ
*------------------------------------------
*/
static int calc_next_walk_step(struct map_session_data *sd)
@@ -3979,12 +3220,11 @@ static int calc_next_walk_step(struct map_session_data *sd)
static int pc_walk(int tid,unsigned int tick,int id,int data)
{
struct map_session_data *sd;
- int i,ctype;
+ int i;
int moveblock;
int x,y,dx,dy;
- sd=map_id2sd(id);
- if(sd==NULL)
+ if ((sd = map_id2sd(id)) == NULL)
return 0;
if(sd->walktimer != tid){
@@ -4001,32 +3241,34 @@ static int pc_walk(int tid,unsigned int tick,int id,int data)
sd->inchealspiritsptick = 0;
sd->walkpath.path_half ^= 1;
- if(sd->walkpath.path_half==0){ // ƒ}ƒX–Ú’†S‚Ö“ž’…
+ if(sd->walkpath.path_half==0){ // ƒ}ƒX–Ú’†S‚Ö“r
sd->walkpath.path_pos++;
+
if(sd->state.change_walk_target){
pc_walktoxy_sub(sd);
return 0;
}
- } else { // ƒ}ƒX–Ú‹«ŠE‚Ö“ž’…
+ } else { // ƒ}ƒX–Ú‹«ŠE‚Ö“r
if(sd->walkpath.path[sd->walkpath.path_pos]>=8)
return 1;
x = sd->bl.x;
y = sd->bl.y;
- ctype = map_getcell(sd->bl.m,x,y);
- if(ctype == 1 || ctype == 5) {
+ if(map_getcell(sd->bl.m,x,y,CELL_CHKNOPASS)) {
pc_stop_walking(sd,1);
return 0;
}
sd->dir=sd->head_dir=sd->walkpath.path[sd->walkpath.path_pos];
dx = dirx[(int)sd->dir];
dy = diry[(int)sd->dir];
- ctype = map_getcell(sd->bl.m,x+dx,y+dy);
- if(ctype == 1 || ctype == 5) {
+ if(map_getcell(sd->bl.m,x,y,CELL_CHKNOPASS)) {
pc_walktoxy_sub(sd);
return 0;
}
-
+ if (skill_check_moonlit (&sd->bl,x+dx,y+dy)) {
+ pc_stop_walking(sd,1);
+ return 0;
+ }
moveblock = ( x/BLOCK_SIZE != (x+dx)/BLOCK_SIZE || y/BLOCK_SIZE != (y+dy)/BLOCK_SIZE);
sd->walktimer = 1;
@@ -4035,26 +3277,12 @@ static int pc_walk(int tid,unsigned int tick,int id,int data)
x += dx;
y += dy;
+ skill_unit_move(&sd->bl,tick,0);
if(moveblock) map_delblock(&sd->bl);
sd->bl.x = x;
sd->bl.y = y;
if(moveblock) map_addblock(&sd->bl);
-
- if (sd->status.guild_id > 0) {
- struct skill_unit *su;
- if (sd->sc_data[SC_LEADERSHIP].val4 && (su=(struct skill_unit *)sd->sc_data[SC_LEADERSHIP].val4)) {
- skill_unit_move_unit_group(su->group,sd->bl.m,dx,dy);
- }
- if (sd->sc_data[SC_GLORYWOUNDS].val4 && (su=(struct skill_unit *)sd->sc_data[SC_GLORYWOUNDS].val4)) {
- skill_unit_move_unit_group(su->group,sd->bl.m,dx,dy);
- }
- if (sd->sc_data[SC_SOULCOLD].val4 && (su=(struct skill_unit *)sd->sc_data[SC_SOULCOLD].val4)) {
- skill_unit_move_unit_group(su->group,sd->bl.m,dx,dy);
- }
- if (sd->sc_data[SC_HAWKEYES].val4 && (su=(struct skill_unit *)sd->sc_data[SC_HAWKEYES].val4)) {
- skill_unit_move_unit_group(su->group,sd->bl.m,dx,dy);
- }
- }
+ skill_unit_move(&sd->bl,tick,1);
map_foreachinmovearea(clif_pcinsight,sd->bl.m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,-dx,-dy,0,sd);
sd->walktimer = -1;
@@ -4084,21 +3312,18 @@ static int pc_walk(int tid,unsigned int tick,int id,int data)
if (sd->sc_data[SC_DEVOTION].val1)
skill_devotion2(&sd->bl,sd->sc_data[SC_DEVOTION].val1);
- if (sd->sc_data[SC_BASILICA].timer != -1) { // Basilica cancels if caster moves [celest]
- struct skill_unit *su;
- if ((su = (struct skill_unit *)sd->sc_data[SC_BASILICA].val4)) {
- struct skill_unit_group *sg;
- if ((sg = su->group) && sg->src_id == sd->bl.id) {
- skill_status_change_end(&sd->bl,SC_BASILICA,-1);
- skill_delunitgroup (sg);
- }
- }
+ if (sd->sc_data[SC_BASILICA].timer!=-1) { // Basilica cancels if caster moves [celest]
+ /*int i;
+ for (i=0;i<MAX_SKILLUNITGROUP;i++)
+ if (sd->skillunit[i].skill_id==HP_BASILICA*/
+ struct skill_unit_group *sg = (struct skill_unit_group *)sd->sc_data[SC_BASILICA].val4;
+ if (sg && sg->src_id == sd->bl.id)
+ skill_delunitgroup (sg);
+ status_change_end(&sd->bl,SC_BASILICA,-1);
}
}
- skill_unit_move(&sd->bl,tick,1); // ƒXƒLƒ‹ƒ†ƒjƒbƒg‚Ì?¸
-
- if(map_getcell(sd->bl.m,x,y)&0x80)
+ if(map_getcell(sd->bl.m,x,y,CELL_CHKNPC))
npc_touch_areanpc(sd,sd->bl.m,x,y);
else
sd->areanpc_id=0;
@@ -4109,6 +3334,8 @@ static int pc_walk(int tid,unsigned int tick,int id,int data)
i = 1;
sd->walktimer=add_timer(tick+i,pc_walk,id,sd->walkpath.path_pos);
}
+ if(battle_config.disp_hpmeter)
+ clif_hpmeter(sd);
return 0;
}
@@ -4151,15 +3378,24 @@ int pc_walktoxy(struct map_session_data *sd,int x,int y)
sd->to_x=x;
sd->to_y=y;
+ sd->idletime = tick_;
if(sd->walktimer != -1 && sd->state.change_walk_target==0){
- // Œ»Ý?‚¢‚Ä‚¢‚éÅ’†‚Ì–Ú“I’n?X‚Ȃ̂Ń}ƒX–Ú‚Ì’†S‚É?‚½Žž‚É
+ // Œ»Ý?‚¢‚Ä‚¢‚éÅ’†‚Ì–Ú“I’n?X‚Ȃ̂Ń}ƒX–Ú‚Ì’†S‚É?‚½ŽbÉ
// timer??‚©‚çpc_walktoxy_sub‚ðŒÄ‚Ԃ悤‚É‚·‚é
sd->state.change_walk_target=1;
} else {
pc_walktoxy_sub(sd);
}
+ if (sd->state.gmaster_flag > 0) {
+ struct guild *g = (struct guild *)sd->state.gmaster_flag;
+ if (g)
+ map_foreachinarea (skill_guildaura_sub, sd->bl.m,
+ sd->bl.x-2, sd->bl.y-2, sd->bl.x+2, sd->bl.y+2, BL_PC,
+ sd->bl.id, sd->status.guild_id, g);
+ }
+
return 0;
}
@@ -4182,7 +3418,7 @@ int pc_stop_walking(struct map_session_data *sd,int type)
clif_fixpos(&sd->bl);
if(type&0x02 && battle_config.pc_damage_delay) {
unsigned int tick = gettick();
- int delay = battle_get_dmotion(&sd->bl);
+ int delay = status_get_dmotion(&sd->bl);
if(sd->canmove_tick < tick)
sd->canmove_tick = tick + delay;
}
@@ -4191,13 +3427,47 @@ int pc_stop_walking(struct map_session_data *sd,int type)
}
/*==========================================
+ * Random walk
+ *------------------------------------------
+ */
+int pc_randomwalk(struct map_session_data *sd,int tick)
+{
+ const int retrycount = 20;
+ nullpo_retr(0, sd);
+
+ if(DIFF_TICK(sd->next_walktime,tick)<0){
+ int i,x,y,d;
+ d = rand()%7+5;
+ for(i=0;i<retrycount;i++){ // Search of a movable place
+ int r=rand();
+ x=sd->bl.x+r%(d*2+1)-d;
+ y=sd->bl.y+r/(d*2+1)%(d*2+1)-d;
+ if((map_getcell(sd->bl.m,x,y,CELL_CHKPASS)) && pc_walktoxy(sd,x,y)==0)
+ break;
+ }
+ // Working on this part later [celest]
+ /*for(i=c=0;i<sd->walkpath.path_len;i++){ // The next walk start time is calculated.
+ if(sd->walkpath.path[i]&1)
+ c+=sd->speed*14/10;
+ else
+ c+=sd->speed;
+ }
+ sd->next_walktime = (d=tick+rand()%3000+c);
+ return d;*/
+ return 1;
+ }
+ return 0;
+}
+
+/*==========================================
*
*------------------------------------------
*/
int pc_movepos(struct map_session_data *sd,int dst_x,int dst_y)
{
int moveblock;
- int dx,dy,dist;
+ int dx,dy;
+ int tick = gettick();
struct walkpath_data wpd;
@@ -4210,16 +3480,17 @@ int pc_movepos(struct map_session_data *sd,int dst_x,int dst_y)
dx = dst_x - sd->bl.x;
dy = dst_y - sd->bl.y;
- dist = distance(sd->bl.x,sd->bl.y,dst_x,dst_y);
moveblock = ( sd->bl.x/BLOCK_SIZE != dst_x/BLOCK_SIZE || sd->bl.y/BLOCK_SIZE != dst_y/BLOCK_SIZE);
map_foreachinmovearea(clif_pcoutsight,sd->bl.m,sd->bl.x-AREA_SIZE,sd->bl.y-AREA_SIZE,sd->bl.x+AREA_SIZE,sd->bl.y+AREA_SIZE,dx,dy,0,sd);
+ skill_unit_move(&sd->bl,tick,0);
if(moveblock) map_delblock(&sd->bl);
sd->bl.x = dst_x;
sd->bl.y = dst_y;
if(moveblock) map_addblock(&sd->bl);
+ skill_unit_move(&sd->bl,tick,1);
map_foreachinmovearea(clif_pcinsight,sd->bl.m,sd->bl.x-AREA_SIZE,sd->bl.y-AREA_SIZE,sd->bl.x+AREA_SIZE,sd->bl.y+AREA_SIZE,-dx,-dy,0,sd);
@@ -4236,9 +3507,7 @@ int pc_movepos(struct map_session_data *sd,int dst_x,int dst_y)
if(sd->status.option&4) // ƒNƒ?ƒLƒ“ƒO‚ÌÁ–Å?¸
skill_check_cloaking(&sd->bl);
- skill_unit_move(&sd->bl,gettick(),dist+7); // ƒXƒLƒ‹ƒ†ƒjƒbƒg‚Ì?¸
-
- if(map_getcell(sd->bl.m,sd->bl.x,sd->bl.y)&0x80)
+ if(map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKNPC))
npc_touch_areanpc(sd,sd->bl.m,sd->bl.x,sd->bl.y);
else
sd->areanpc_id=0;
@@ -4281,46 +3550,44 @@ int pc_checkskill(struct map_session_data *sd,int skill_id)
int pc_checkallowskill(struct map_session_data *sd)
{
nullpo_retr(0, sd);
-
- if( sd->sc_data == NULL )
- return 0;
+ nullpo_retr(0, sd->sc_data);
if(!(skill_get_weapontype(KN_TWOHANDQUICKEN)&(1<<sd->status.weapon)) && sd->sc_data[SC_TWOHANDQUICKEN].timer!=-1) { // 2HQ
- skill_status_change_end(&sd->bl,SC_TWOHANDQUICKEN,-1); // 2HQ‚ð‰ðœ
+ status_change_end(&sd->bl,SC_TWOHANDQUICKEN,-1); // 2HQ‚ð‰ðœ
return -1;
}
if(!(skill_get_weapontype(LK_AURABLADE)&(1<<sd->status.weapon)) && sd->sc_data[SC_AURABLADE].timer!=-1) { /* ƒI?ƒ‰ƒuƒŒ?ƒh */
- skill_status_change_end(&sd->bl,SC_AURABLADE,-1); /* ƒI?ƒ‰ƒuƒŒ?ƒh‚ð‰ðœ */
+ status_change_end(&sd->bl,SC_AURABLADE,-1); /* ƒI?ƒ‰ƒuƒŒ?ƒh‚ð‰ðœ */
return -1;
}
if(!(skill_get_weapontype(LK_PARRYING)&(1<<sd->status.weapon)) && sd->sc_data[SC_PARRYING].timer!=-1) { /* ƒpƒŠƒCƒ“ƒO */
- skill_status_change_end(&sd->bl,SC_PARRYING,-1); /* ƒpƒŠƒCƒ“ƒO‚ð‰ðœ */
+ status_change_end(&sd->bl,SC_PARRYING,-1); /* ƒpƒŠƒCƒ“ƒO‚ð‰ðœ */
return -1;
}
if(!(skill_get_weapontype(LK_CONCENTRATION)&(1<<sd->status.weapon)) && sd->sc_data[SC_CONCENTRATION].timer!=-1) { /* ƒRƒ“ƒZƒ“ƒgƒŒ?ƒVƒ‡ƒ“ */
- skill_status_change_end(&sd->bl,SC_CONCENTRATION,-1); /* ƒRƒ“ƒZƒ“ƒgƒŒ?ƒVƒ‡ƒ“‚ð‰ðœ */
+ status_change_end(&sd->bl,SC_CONCENTRATION,-1); /* ƒRƒ“ƒZƒ“ƒgƒŒ?ƒVƒ‡ƒ“‚ð‰ðœ */
return -1;
}
if(!(skill_get_weapontype(CR_SPEARQUICKEN)&(1<<sd->status.weapon)) && sd->sc_data[SC_SPEARSQUICKEN].timer!=-1){ // ƒXƒsƒAƒNƒBƒbƒPƒ“
- skill_status_change_end(&sd->bl,SC_SPEARSQUICKEN,-1); // ƒXƒsƒAƒNƒCƒbƒPƒ“‚ð‰ðœ
+ status_change_end(&sd->bl,SC_SPEARSQUICKEN,-1); // ƒXƒsƒAƒNƒCƒbƒPƒ“‚ð‰ðœ
return -1;
}
if(!(skill_get_weapontype(BS_ADRENALINE)&(1<<sd->status.weapon)) && sd->sc_data[SC_ADRENALINE].timer!=-1){ // ƒAƒhƒŒƒiƒŠƒ“ƒ‰ƒbƒVƒ…
- skill_status_change_end(&sd->bl,SC_ADRENALINE,-1); // ƒAƒhƒŒƒiƒŠƒ“ƒ‰ƒbƒVƒ…‚ð‰ðœ
+ status_change_end(&sd->bl,SC_ADRENALINE,-1); // ƒAƒhƒŒƒiƒŠƒ“ƒ‰ƒbƒVƒ…‚ð‰ðœ
return -1;
}
if(sd->status.shield <= 0) {
if(sd->sc_data[SC_AUTOGUARD].timer!=-1){ // ƒI?ƒgƒK?ƒh
- skill_status_change_end(&sd->bl,SC_AUTOGUARD,-1);
+ status_change_end(&sd->bl,SC_AUTOGUARD,-1);
return -1;
}
if(sd->sc_data[SC_DEFENDER].timer!=-1){ // ƒfƒBƒtƒFƒ“ƒ_?
- skill_status_change_end(&sd->bl,SC_DEFENDER,-1);
+ status_change_end(&sd->bl,SC_DEFENDER,-1);
return -1;
}
if(sd->sc_data[SC_REFLECTSHIELD].timer!=-1){ //ƒŠƒtƒŒƒNƒgƒV?ƒ‹ƒh
- skill_status_change_end(&sd->bl,SC_REFLECTSHIELD,-1);
+ status_change_end(&sd->bl,SC_REFLECTSHIELD,-1);
return -1;
}
}
@@ -4372,10 +3639,6 @@ struct pc_base_job pc_calc_base_job(int b_class)
bj.upper = 2;
}
- if(battle_config.enable_upper_class==0){ //conf‚Å–³?‚ɂȂÁ‚Ä‚¢‚½‚çupper=0
- bj.upper = 0;
- }
-
if(bj.job == 0){
bj.type = 0;
}else if(bj.job < 7){
@@ -4383,7 +3646,7 @@ struct pc_base_job pc_calc_base_job(int b_class)
}else{
bj.type = 2;
}
-
+
return bj;
}
@@ -4399,7 +3662,7 @@ int pc_calc_base_job2 (int b_class)
return b_class - 4001;
else if(b_class == 4045)
return 23;
- return b_class - 4023;
+ return b_class - 4023;
}
int pc_calc_upper(int b_class)
@@ -4426,6 +3689,9 @@ int pc_attack_timer(int tid,unsigned int tick,int id,int data)
sd=map_id2sd(id);
if(sd == NULL)
return 0;
+
+ sd->idletime = tick_;
+
if(sd->attacktimer != tid){
if(battle_config.error_log)
printf("pc_attack_timer %d != %d\n",sd->attacktimer,tid);
@@ -4440,8 +3706,12 @@ int pc_attack_timer(int tid,unsigned int tick,int id,int data)
if(bl==NULL || bl->prev == NULL)
return 0;
- if(bl->type == BL_PC && pc_isdead((struct map_session_data *)bl))
- return 0;
+ if(bl->type == BL_PC) {
+ if (pc_isdead((struct map_session_data *)bl))
+ return 0;
+ else if (pc_ishiding((struct map_session_data *)bl))
+ return 0;
+ }
// “¯‚¶map‚łȂ¢‚È‚çU?‚µ‚È‚¢
// PC‚ªŽ€‚ñ‚łĂàU?‚µ‚È‚¢
@@ -4452,17 +3722,21 @@ int pc_attack_timer(int tid,unsigned int tick,int id,int data)
if( sd->opt1>0 || sd->status.option&2 || sd->status.option&16384) // ˆÙí‚ȂǂÅU?‚Å‚«‚È‚¢
return 0;
- if(sd->sc_data[SC_AUTOCOUNTER].timer != -1)
- return 0;
- if(sd->sc_data[SC_BLADESTOP].timer != -1)
- return 0;
+ if (sd->sc_count) {
+ if(sd->sc_data[SC_AUTOCOUNTER].timer != -1)
+ return 0;
+ if(sd->sc_data[SC_BLADESTOP].timer != -1)
+ return 0;
+ }
- //if((opt = battle_get_option(bl)) != NULL && *opt&0x46)
- if((opt = battle_get_option(bl)) != NULL && *opt&0x42)
+ //if((opt = status_get_option(bl)) != NULL && *opt&0x46)
+ if((opt = status_get_option(bl)) != NULL && *opt&0x42)
return 0;
- if(((sc_data = battle_get_sc_data(bl)) != NULL && sc_data[SC_TRICKDEAD].timer != -1) ||
- ((sc_data = battle_get_sc_data(bl)) != NULL && sc_data[SC_BASILICA].timer != -1 ))
+ if((sc_data = status_get_sc_data(bl)) != NULL) {
+ if (sc_data[SC_TRICKDEAD].timer != -1 ||
+ sc_data[SC_BASILICA].timer != -1)
return 0;
+ }
if(sd->skilltimer != -1 && pc_checkskill(sd,SA_FREECAST) <= 0)
return 0;
@@ -4474,6 +3748,11 @@ int pc_attack_timer(int tid,unsigned int tick,int id,int data)
}
}
+ if(sd->status.weapon == 11 && sd->equip_index[10] < 0) {
+ clif_arrow_fail(sd,0);
+ return 0;
+ }
+
dist = distance(sd->bl.x,sd->bl.y,bl->x,bl->y);
range = sd->attackrange;
if(sd->status.weapon != 11) range++;
@@ -4501,7 +3780,7 @@ int pc_attack_timer(int tid,unsigned int tick,int id,int data)
sd->attacktarget_lv = battle_weapon_attack(&sd->bl,bl,tick,0);
// &2 = ? - Celest
if(!(battle_config.pc_cloak_check_type&2) && sd->sc_data[SC_CLOAKING].timer != -1)
- skill_status_change_end(&sd->bl,SC_CLOAKING,-1);
+ status_change_end(&sd->bl,SC_CLOAKING,-1);
if(sd->status.pet_id > 0 && sd->pd && sd->petDB && battle_config.pet_attack_support)
pet_target_check(sd,bl,0);
map_freeblock_unlock();
@@ -4536,19 +3815,22 @@ int pc_attack(struct map_session_data *sd,int target_id,int type)
struct block_list *bl;
int d;
+
nullpo_retr(0, sd);
bl=map_id2bl(target_id);
if(bl==NULL)
return 1;
-
+
+ sd->idletime = tick_;
+
if(bl->type==BL_NPC) { // monster npcs [Valaris]
//npc_click(sd,RFIFOL(sd->fd,2));
npc_click(sd,target_id); // submitted by leinsirk10 [Celest]
return 0;
}
-
- if(!battle_check_target(&sd->bl,bl,BCT_ENEMY))
+
+ if(battle_check_target(&sd->bl,bl,BCT_ENEMY) <= 0)
return 1;
if(sd->attacktimer != -1)
pc_stopattack(sd);
@@ -4589,7 +3871,8 @@ int pc_follow_timer(int tid,unsigned int tick,int id,int data)
struct map_session_data *sd, *bl;
sd=map_id2sd(id);
- if(sd == NULL || sd->followtimer != tid)
+
+ if(sd == NULL || sd->followtimer != tid || pc_isdead(sd))
return 0;
sd->followtimer=-1;
@@ -4648,7 +3931,7 @@ int pc_checkbaselevelup(struct map_session_data *sd)
nullpo_retr(0, sd);
if(sd->status.base_exp >= next && next > 0){
- struct pc_base_job s_class = pc_calc_base_job(sd->status.class);
+ struct pc_base_job s_class = pc_calc_base_job(sd->status.class_);
// base‘¤ƒŒƒxƒ‹ƒAƒbƒv?—
sd->status.base_exp -= next;
@@ -4658,16 +3941,16 @@ int pc_checkbaselevelup(struct map_session_data *sd)
clif_updatestatus(sd,SP_STATUSPOINT);
clif_updatestatus(sd,SP_BASELEVEL);
clif_updatestatus(sd,SP_NEXTBASEEXP);
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
pc_heal(sd,sd->status.max_hp,sd->status.max_sp);
//ƒXƒpƒmƒr‚̓LƒŠƒGAƒCƒ€ƒ|Aƒ}ƒjƒsAƒOƒAƒTƒtƒ‰Lv1‚ª‚©‚©‚é
if(s_class.job == 23){
- skill_status_change_start(&sd->bl,SkillStatusChangeTable[PR_KYRIE],1,0,0,0,skill_get_time(PR_KYRIE,1),0 );
- skill_status_change_start(&sd->bl,SkillStatusChangeTable[PR_IMPOSITIO],1,0,0,0,skill_get_time(PR_IMPOSITIO,1),0 );
- skill_status_change_start(&sd->bl,SkillStatusChangeTable[PR_MAGNIFICAT],1,0,0,0,skill_get_time(PR_MAGNIFICAT,1),0 );
- skill_status_change_start(&sd->bl,SkillStatusChangeTable[PR_GLORIA],1,0,0,0,skill_get_time(PR_GLORIA,1),0 );
- skill_status_change_start(&sd->bl,SkillStatusChangeTable[PR_SUFFRAGIUM],1,0,0,0,skill_get_time(PR_SUFFRAGIUM,1),0 );
+ status_change_start(&sd->bl,SkillStatusChangeTable[PR_KYRIE],1,0,0,0,skill_get_time(PR_KYRIE,1),0 );
+ status_change_start(&sd->bl,SkillStatusChangeTable[PR_IMPOSITIO],1,0,0,0,skill_get_time(PR_IMPOSITIO,1),0 );
+ status_change_start(&sd->bl,SkillStatusChangeTable[PR_MAGNIFICAT],1,0,0,0,skill_get_time(PR_MAGNIFICAT,1),0 );
+ status_change_start(&sd->bl,SkillStatusChangeTable[PR_GLORIA],1,0,0,0,skill_get_time(PR_GLORIA,1),0 );
+ status_change_start(&sd->bl,SkillStatusChangeTable[PR_SUFFRAGIUM],1,0,0,0,skill_get_time(PR_SUFFRAGIUM,1),0 );
}
clif_misceffect(&sd->bl,0);
@@ -4694,7 +3977,7 @@ int pc_checkjoblevelup(struct map_session_data *sd)
clif_updatestatus(sd,SP_NEXTJOBEXP);
sd->status.skill_point ++;
clif_updatestatus(sd,SP_SKILLPOINT);
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
clif_misceffect(&sd->bl,1);
return 1;
@@ -4710,6 +3993,8 @@ int pc_checkjoblevelup(struct map_session_data *sd)
int pc_gainexp(struct map_session_data *sd,int base_exp,int job_exp)
{
char output[256];
+ float nextbp=0, nextjp=0;
+ int nextb=0, nextj=0;
nullpo_retr(0, sd);
if(sd->bl.prev == NULL || pc_isdead(sd))
@@ -4734,11 +4019,17 @@ int pc_gainexp(struct map_session_data *sd,int base_exp,int job_exp)
if (base_exp < 0)
base_exp = 0;
}
+ nextb = pc_nextbaseexp(sd);
+ nextj = pc_nextjobexp(sd);
+ if (nextb > 0)
+ nextbp = (float) base_exp / (float) nextb;
+ if (nextj > 0)
+ nextjp = (float) job_exp / (float) nextj;
sd->status.base_exp += base_exp;
if(sd->status.base_exp < 0)
sd->status.base_exp = 0;
-
+
while(pc_checkbaselevelup(sd)) ;
clif_updatestatus(sd,SP_BASEEXP);
@@ -4751,14 +4042,14 @@ int pc_gainexp(struct map_session_data *sd,int base_exp,int job_exp)
sd->status.job_exp += job_exp;
if(sd->status.job_exp < 0)
sd->status.job_exp = 0;
-
+
while(pc_checkjoblevelup(sd)) ;
clif_updatestatus(sd,SP_JOBEXP);
- if(battle_config.disp_experience){
- sprintf(output,
- "Experienced Gained Base:%d Job:%d",base_exp,job_exp);
+ if(battle_config.disp_experience && !sd->noexp){
+ sprintf(output,
+ "Experienced Gained Base:%d (%.2f%%) Job:%d (%.2f%%)",base_exp,nextbp*(float)100,job_exp,nextjp*(float)100);
clif_disp_onlyself(sd,output,strlen(output));
}
@@ -4778,12 +4069,12 @@ int pc_nextbaseexp(struct map_session_data *sd)
if(sd->status.base_level>=MAX_LEVEL || sd->status.base_level<=0)
return 0;
- if(sd->status.class==0) i=0;
- else if(sd->status.class<=6) i=1;
- else if(sd->status.class<=22) i=2;
- else if(sd->status.class==23) i=3;
- else if(sd->status.class==4001) i=4;
- else if(sd->status.class<=4007) i=5;
+ if(sd->status.class_==0) i=0;
+ else if(sd->status.class_<=6) i=1;
+ else if(sd->status.class_<=22) i=2;
+ else if(sd->status.class_==23) i=3;
+ else if(sd->status.class_==4001) i=4;
+ else if(sd->status.class_<=4007) i=5;
else i=6;
return exp_table[i][sd->status.base_level-1];
@@ -4802,12 +4093,12 @@ int pc_nextjobexp(struct map_session_data *sd)
if(sd->status.job_level>=MAX_LEVEL || sd->status.job_level<=0)
return 0;
- if(sd->status.class==0) i=7;
- else if(sd->status.class<=6) i=8;
- else if(sd->status.class<=22) i=9;
- else if(sd->status.class==23) i=10;
- else if(sd->status.class==4001) i=11;
- else if(sd->status.class<=4007) i=12;
+ if(sd->status.class_==0) i=7;
+ else if(sd->status.class_<=6) i=8;
+ else if(sd->status.class_<=22) i=9;
+ else if(sd->status.class_==23) i=10;
+ else if(sd->status.class_==4001) i=11;
+ else if(sd->status.class_<=4007) i=12;
else i=13;
return exp_table[i][sd->status.job_level-1];
@@ -4826,12 +4117,12 @@ int pc_nextbaseafter(struct map_session_data *sd)
if(sd->status.base_level>=MAX_LEVEL || sd->status.base_level<=0)
return 0;
- if(sd->status.class==0) i=0;
- else if(sd->status.class<=6) i=1;
- else if(sd->status.class<=22) i=2;
- else if(sd->status.class==23) i=3;
- else if(sd->status.class==4001) i=4;
- else if(sd->status.class<=4007) i=5;
+ if(sd->status.class_==0) i=0;
+ else if(sd->status.class_<=6) i=1;
+ else if(sd->status.class_<=22) i=2;
+ else if(sd->status.class_==23) i=3;
+ else if(sd->status.class_==4001) i=4;
+ else if(sd->status.class_<=4007) i=5;
else i=6;
return exp_table[i][sd->status.base_level];
@@ -4850,12 +4141,12 @@ int pc_nextjobafter(struct map_session_data *sd)
if(sd->status.job_level>=MAX_LEVEL || sd->status.job_level<=0)
return 0;
- if(sd->status.class==0) i=7;
- else if(sd->status.class<=6) i=8;
- else if(sd->status.class<=22) i=9;
- else if(sd->status.class==23) i=10;
- else if(sd->status.class==4001) i=11;
- else if(sd->status.class<=4007) i=12;
+ if(sd->status.class_==0) i=7;
+ else if(sd->status.class_<=6) i=8;
+ else if(sd->status.class_<=22) i=9;
+ else if(sd->status.class_==23) i=10;
+ else if(sd->status.class_==4001) i=11;
+ else if(sd->status.class_<=4007) i=12;
else i=13;
return exp_table[i][sd->status.job_level];
@@ -4890,10 +4181,10 @@ int pc_need_status_point(struct map_session_data *sd,int type)
int pc_statusup(struct map_session_data *sd,int type)
{
int max, need,val = 0;
-
+
nullpo_retr(0, sd);
- max = (pc_calc_upper(sd->status.class)==2) ? 80 : battle_config.max_parameter;
+ max = (pc_calc_upper(sd->status.class_)==2) ? 80 : battle_config.max_parameter;
need=pc_need_status_point(sd,type);
if(type<SP_STR || type>SP_LUK || need<0 || need>sd->status.status_point){
@@ -4950,7 +4241,7 @@ int pc_statusup(struct map_session_data *sd,int type)
}
clif_updatestatus(sd,SP_STATUSPOINT);
clif_updatestatus(sd,type);
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
clif_statusupack(sd,type,1,val);
return 0;
@@ -5026,7 +4317,7 @@ int pc_statusup2(struct map_session_data *sd,int type,int val)
}
clif_updatestatus(sd,type-SP_STR+SP_USTR);
clif_updatestatus(sd,type);
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
clif_statusupack(sd,type,1,val);
return 0;
@@ -5048,11 +4339,11 @@ int pc_skillup(struct map_session_data *sd,int skill_num)
if( sd->status.skill_point>0 &&
sd->status.skill[skill_num].id!=0 &&
//sd->status.skill[skill_num].lv < skill_get_max(skill_num) ) - celest
- sd->status.skill[skill_num].lv < skill_tree_get_max(skill_num, sd->status.class) )
+ sd->status.skill[skill_num].lv < skill_tree_get_max(skill_num, sd->status.class_) )
{
sd->status.skill[skill_num].lv++;
sd->status.skill_point--;
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
clif_skillup(sd,skill_num);
clif_updatestatus(sd,SP_SKILLPOINT);
clif_skillinfoblock(sd);
@@ -5074,7 +4365,7 @@ int pc_allskillup(struct map_session_data *sd)
nullpo_retr(0, sd);
- s_class = pc_calc_base_job(sd->status.class);
+ s_class = pc_calc_base_job(sd->status.class_);
c = s_class.job;
s = (s_class.upper==1) ? 1 : 0 ; //?¶ˆÈŠO‚Í’Êí‚̃XƒLƒ‹H
@@ -5092,21 +4383,25 @@ int pc_allskillup(struct map_session_data *sd)
sd->status.skill[i].lv=skill_get_max(i);
for(i=210;i<291;i++)
sd->status.skill[i].lv=skill_get_max(i);
- for(i=304;i<MAX_SKILL;i++){
+ for(i=304;i<338;i++){
if(i==331) continue;
sd->status.skill[i].lv=skill_get_max(i);
}
+ for(i=355;i<411;i++)
+ sd->status.skill[i].lv=skill_get_max(i);
+ for(i=475;i<480;i++)
+ sd->status.skill[i].lv=skill_get_max(i);
}
else {
for(i=0;(id=skill_tree[s][c][i].id)>0;i++){
if(sd->status.skill[id].id==0 && (!(skill_get_inf2(id)&0x01) || battle_config.quest_skill_learn) ) {
sd->status.skill[id].id = id; // celest
// sd->status.skill[id].lv=skill_get_max(id);
- sd->status.skill[id].lv = skill_tree_get_max(id, sd->status.class); // celest
+ sd->status.skill[id].lv = skill_tree_get_max(id, sd->status.class_); // celest
}
}
}
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
return 0;
}
@@ -5118,9 +4413,9 @@ int pc_allskillup(struct map_session_data *sd)
int pc_resetlvl(struct map_session_data* sd,int type)
{
int i;
-
+
nullpo_retr(0, sd);
-
+
for(i=1;i<MAX_SKILL;i++){
sd->status.skill[i].lv = 0;
}
@@ -5140,8 +4435,11 @@ int pc_resetlvl(struct map_session_data* sd,int type)
sd->status.int_=1;
sd->status.dex=1;
sd->status.luk=1;
- if(sd->status.class == 4001)
- sd->status.status_point=88;
+ if(sd->status.class_ == 4001)
+ sd->status.status_point=100; // not 88 [celest]
+ // give platinum skills upon changing
+ pc_skill(sd,142,1,0);
+ pc_skill(sd,143,1,0);
}
if(type == 2){
@@ -5158,7 +4456,7 @@ int pc_resetlvl(struct map_session_data* sd,int type)
if(type == 4){
sd->status.job_level=1;
sd->status.job_exp=0;
- }
+ }
clif_updatestatus(sd,SP_STATUSPOINT);
clif_updatestatus(sd,SP_STR);
@@ -5184,11 +4482,11 @@ int pc_resetlvl(struct map_session_data* sd,int type)
for(i=0;i<11;i++) { // unequip items that can't be equipped by base 1 [Valaris]
if(sd->equip_index[i] >= 0)
if(!pc_isequip(sd,sd->equip_index[i]))
- pc_unequipitem(sd,sd->equip_index[i],1,BF_NORMAL);
+ pc_unequipitem(sd,sd->equip_index[i],2);
}
clif_skillinfoblock(sd);
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
return 0;
}
@@ -5200,14 +4498,17 @@ int pc_resetstate(struct map_session_data* sd)
{
#define sumsp(a) ((a)*((a-2)/10+2) - 5*((a-2)/10)*((a-2)/10) - 6*((a-2)/10) -2)
// int add=0; // Removed by Dexity
+ int lv;
nullpo_retr(0, sd);
+ // allow it to just read the last entry [celest]
+ lv = sd->status.base_level < MAX_LEVEL ? sd->status.base_level : MAX_LEVEL - 1;
// New statpoint table used here - Dexity
- sd->status.status_point = atoi (statp[sd->status.base_level - 1]);
- if(sd->status.class >= 4001 && sd->status.class <= 4024)
- sd->status.status_point+=40;
-// End addition
+ sd->status.status_point = statp[lv];
+ if(sd->status.class_ >= 4001 && sd->status.class_ <= 4024)
+ sd->status.status_point+=52; // extra 52+48=100 stat points
+// End addition
// Removed by Dexity - old count
// add += sumsp(sd->status.str);
@@ -5241,7 +4542,7 @@ int pc_resetstate(struct map_session_data* sd)
clif_updatestatus(sd,SP_UDEX);
clif_updatestatus(sd,SP_ULUK); // End Addition
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
return 0;
}
@@ -5257,7 +4558,8 @@ int pc_resetskill(struct map_session_data* sd)
nullpo_retr(0, sd);
for(i=1;i<MAX_SKILL;i++){
- if( (skill = pc_checkskill(sd,i)) > 0) {
+ skill = ( i >= 10000 ) ? pc_checkskill(sd,i) : sd->status.skill[i].lv;
+ if( skill > 0) {
if(!(skill_get_inf2(i)&0x01) || battle_config.quest_skill_learn) {
if(!sd->status.skill[i].flag)
sd->status.skill_point += skill;
@@ -5269,13 +4571,13 @@ int pc_resetskill(struct map_session_data* sd)
else if(battle_config.quest_skill_reset)
sd->status.skill[i].lv = 0;
sd->status.skill[i].flag = 0;
- }
- else
+ } else {
sd->status.skill[i].lv = 0;
+ }
}
clif_updatestatus(sd,SP_SKILLPOINT);
clif_skillinfoblock(sd);
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
return 0;
}
@@ -5292,7 +4594,7 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage)
nullpo_retr(0, sd);
//?¶‚â—{Žq‚Ìꇂ̌³‚ÌE‹Æ‚ðŽZo‚·‚é
- s_class = pc_calc_base_job(sd->status.class);
+ s_class = pc_calc_base_job(sd->status.class_);
// ?‚ÉŽ€‚ñ‚Å‚¢‚½‚ç–³?
if(pc_isdead(sd))
return 0;
@@ -5303,11 +4605,16 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage)
}
// ? ‚¢‚Ä‚¢‚½‚ç‘«‚ðŽ~‚ß‚é
- if(sd->sc_data[SC_ENDURE].timer == -1 && sd->sc_data[SC_BERSERK].timer && !sd->special_state.infinite_endure)
- pc_stop_walking(sd,3);
- else if(sd->sc_data[SC_ENDURE].timer != -1 && src->type==BL_MOB) // [Celest]
- if((--sd->sc_data[SC_ENDURE].val2) <= 0)
- skill_status_change_end(&sd->bl, SC_ENDURE, -1);
+ if (sd->sc_data) {
+ if (sd->sc_data[SC_BERSERK].timer != -1 ||
+ sd->special_state.infinite_endure)
+ ; // do nothing
+ else if (sd->sc_data[SC_ENDURE].timer != -1 && (src != NULL && src->type == BL_MOB) && !map[sd->bl.m].flag.gvg) {
+ if ((--sd->sc_data[SC_ENDURE].val2) < 0)
+ status_change_end(&sd->bl, SC_ENDURE, -1);
+ } else pc_stop_walking(sd,3);
+ }
+
// ‰‰‘t/ƒ_ƒ“ƒX‚Ì’†?
if(damage > sd->status.max_hp>>2)
skill_stop_dancing(&sd->bl,0);
@@ -5317,22 +4624,23 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage)
pet_target_check(sd,src,1);
if (sd->sc_data[SC_TRICKDEAD].timer != -1)
- skill_status_change_end(&sd->bl, SC_TRICKDEAD, -1);
+ status_change_end(&sd->bl, SC_TRICKDEAD, -1);
if(sd->status.option&2)
- skill_status_change_end(&sd->bl, SC_HIDING, -1);
+ status_change_end(&sd->bl, SC_HIDING, -1);
if(sd->status.option&4)
- skill_status_change_end(&sd->bl, SC_CLOAKING, -1);
- if(sd->status.option&16386)
- skill_status_change_end(&sd->bl, SC_CHASEWALK, -1);
+ status_change_end(&sd->bl, SC_CLOAKING, -1);
+ if(sd->status.option&16384)
+ status_change_end(&sd->bl, SC_CHASEWALK, -1);
if(sd->status.hp>0){
// ‚Ü‚¾¶‚«‚Ä‚¢‚é‚È‚çHPXV
clif_updatestatus(sd,SP_HP);
- if(sd->status.hp<sd->status.max_hp>>2 && pc_checkskill(sd,SM_AUTOBERSERK)>0 &&
+ //if(sd->status.hp<sd->status.max_hp>>2 && pc_checkskill(sd,SM_AUTOBERSERK)>0 &&
+ if(sd->status.hp<sd->status.max_hp>>2 && sd->sc_data[SC_AUTOBERSERK].timer != -1 &&
(sd->sc_data[SC_PROVOKE].timer==-1 || sd->sc_data[SC_PROVOKE].val2==0 ))
// ƒI?ƒgƒo?ƒT?ƒN?“®
- skill_status_change_start(&sd->bl,SC_PROVOKE,10,1,0,0,0,0);
+ status_change_start(&sd->bl,SC_PROVOKE,10,1,0,0,0,0);
sd->canlog_tick = gettick();
@@ -5344,7 +4652,7 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage)
return 0;
}
sd->status.hp = 0;
- pc_setdead(sd);
+ //pc_setdead(sd);
if(sd->vender_id)
vending_closevending(sd);
@@ -5360,45 +4668,104 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage)
pc_stop_walking(sd,0);
skill_castcancel(&sd->bl,0); // ‰r¥‚Ì’†Ž~
clif_clearchar_area(&sd->bl,1);
- skill_unit_out_all(&sd->bl,gettick(),1);
+ pc_setdead(sd);
+ skill_unit_move(&sd->bl,gettick(),0);
if(sd->sc_data[SC_BLADESTOP].timer!=-1)//”’n‚ÍŽ–‘O‚ɉðœ
- skill_status_change_end(&sd->bl,SC_BLADESTOP,-1);
+ status_change_end(&sd->bl,SC_BLADESTOP,-1);
pc_setglobalreg(sd,"PC_DIE_COUNTER",++sd->die_counter); //Ž€‚ɃJƒEƒ“ƒ^?‘‚«?‚Ý
- skill_status_change_clear(&sd->bl,0); // ƒXƒe?ƒ^ƒXˆÙí‚ð‰ðœ‚·‚é
+ status_change_clear(&sd->bl,0); // ƒXƒe?ƒ^ƒXˆÙí‚ð‰ðœ‚·‚é
clif_updatestatus(sd,SP_HP);
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
+
+ if (src && src->type == BL_PC) {
+ struct map_session_data *ssd = (struct map_session_data *)src;
+ if (ssd) {
+ if (sd->state.event_death)
+ pc_setglobalreg(sd,"killerrid",(ssd->status.account_id));
+ if (ssd->state.event_kill) {
+ if (script_config.event_script_type == 0) {
+ struct npc_data *npc;
+ if ((npc = npc_name2id(script_config.kill_event_name))) {
+ run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCKillNPC
+ sprintf (tmp_output, "Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.kill_event_name);
+ ShowStatus(tmp_output);
+ }
+ } else {
+ sprintf (tmp_output, "%d '"CL_WHITE"%s"CL_RESET"' events executed.\n",
+ npc_event_doall_id(script_config.kill_event_name, sd->bl.id), script_config.kill_event_name);
+ ShowStatus(tmp_output);
+ }
+ }
+ }
+ }
+
+ if (sd->state.event_death) {
+ if (script_config.event_script_type == 0) {
+ struct npc_data *npc;
+ if ((npc = npc_name2id(script_config.die_event_name))) {
+ run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCDeathNPC
+ sprintf (tmp_output, "Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.die_event_name);
+ ShowStatus(tmp_output);
+ }
+ } else {
+ sprintf (tmp_output, "%d '"CL_WHITE"%s"CL_RESET"' events executed.\n",
+ npc_event_doall_id(script_config.die_event_name, sd->bl.id), script_config.die_event_name);
+ ShowStatus(tmp_output);
+ }
+ }
+
+ if(battle_config.bone_drop==2
+ || (battle_config.bone_drop==1 && map[sd->bl.m].flag.pvp)){ // ƒhƒNƒƒhƒƒbƒv
+ struct item item_tmp;
+ memset(&item_tmp,0,sizeof(item_tmp));
+ item_tmp.nameid=7005;
+ item_tmp.identify=1;
+ item_tmp.card[0]=0x00fe;
+ item_tmp.card[1]=0;
+ *((unsigned long *)(&item_tmp.card[2]))=sd->char_id; /* ƒLƒƒƒ‰ID */
+ map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0);
+ }
+
+ // activate Steel body if a super novice dies at 99+% exp [celest]
+ if (s_class.job == 23) {
+ if ((i=pc_nextbaseexp(sd))<=0)
+ i=sd->status.base_exp;
+ if (i>0 && (j=sd->status.base_exp*1000/i)>=990 && j<=1000)
+ sd->state.snovice_flag = 4;
+ }
for(i=0;i<5;i++)
if(sd->dev.val1[i]){
- skill_status_change_end(&map_id2sd(sd->dev.val1[i])->bl,SC_DEVOTION,-1);
+ status_change_end(&map_id2sd(sd->dev.val1[i])->bl,SC_DEVOTION,-1);
sd->dev.val1[i] = sd->dev.val2[i]=0;
}
if(battle_config.death_penalty_type>0) { // changed penalty options, added death by player if pk_mode [Valaris]
- if(sd->status.class != 0 && !map[sd->bl.m].flag.nopenalty && !map[sd->bl.m].flag.gvg){ // only novices will recieve no penalty
+ if(sd->status.class_ != 0 && !map[sd->bl.m].flag.nopenalty && !map[sd->bl.m].flag.gvg && // only novices will recieve no penalty
+ !(sd->sc_count && sd->sc_data[SC_BABY].timer!=-1)) {
if(battle_config.death_penalty_type==1 && battle_config.death_penalty_base > 0)
- sd->status.base_exp -= (double)pc_nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000;
+ sd->status.base_exp -= (int) ((double)pc_nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000);
if(battle_config.pk_mode && src && src->type==BL_PC)
- sd->status.base_exp -= (double)pc_nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000;
+ sd->status.base_exp -= (int) ((double)pc_nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000);
else if(battle_config.death_penalty_type==2 && battle_config.death_penalty_base > 0) {
if(pc_nextbaseexp(sd) > 0)
- sd->status.base_exp -= (double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000;
+ sd->status.base_exp -= (int) ((double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000);
if(battle_config.pk_mode && src && src->type==BL_PC)
- sd->status.base_exp -= (double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000;
+ sd->status.base_exp -= (int) ((double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000);
}
if(sd->status.base_exp < 0)
sd->status.base_exp = 0;
clif_updatestatus(sd,SP_BASEEXP);
if(battle_config.death_penalty_type==1 && battle_config.death_penalty_job > 0)
- sd->status.job_exp -= (double)pc_nextjobexp(sd) * (double)battle_config.death_penalty_job/10000;
+ sd->status.job_exp -= (int) ((double)pc_nextjobexp(sd) * (double)battle_config.death_penalty_job/10000);
if(battle_config.pk_mode && src && src->type==BL_PC)
- sd->status.job_exp -= (double)pc_nextjobexp(sd) * (double)battle_config.death_penalty_job/10000;
+ sd->status.job_exp -= (int) ((double)pc_nextjobexp(sd) * (double)battle_config.death_penalty_job/10000);
else if(battle_config.death_penalty_type==2 && battle_config.death_penalty_job > 0) {
if(pc_nextjobexp(sd) > 0)
- sd->status.job_exp -= (double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000;
+ sd->status.job_exp -= (int) ((double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000);
if(battle_config.pk_mode && src && src->type==BL_PC)
- sd->status.job_exp -= (double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000;
+ sd->status.job_exp -= (int) ((double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000);
}
if(sd->status.job_exp < 0)
sd->status.job_exp = 0;
@@ -5415,7 +4782,7 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage)
if(md && md->state.state!=MS_DEAD && md->level < 99) {
clif_misceffect(&md->bl,0);
md->level++;
- md->hp+=sd->status.max_hp*.1;
+ md->hp+=(int) (sd->status.max_hp*.1);
}
}
@@ -5450,7 +4817,7 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage)
int n = eq_n[rand()%eq_num];//ŠY?ƒAƒCƒeƒ€‚Ì’†‚©‚烉ƒ“ƒ_ƒ€
if(rand()%10000 < per){
if(sd->status.inventory[n].equip)
- pc_unequipitem(sd,n,0,BF_NORMAL);
+ pc_unequipitem(sd,n,3);
pc_dropitem(sd,n,1);
}
}
@@ -5463,7 +4830,7 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage)
|| (type == 2 && sd->status.inventory[i].equip)
|| type == 3) ){
if(sd->status.inventory[i].equip)
- pc_unequipitem(sd,i,0,BF_NORMAL);
+ pc_unequipitem(sd,i,3);
pc_dropitem(sd,i,1);
break;
}
@@ -5510,8 +4877,8 @@ int pc_readparam(struct map_session_data *sd,int type)
{
int val=0;
struct pc_base_job s_class;
-
- s_class = pc_calc_base_job(sd->status.class);
+
+ s_class = pc_calc_base_job(sd->status.class_);
nullpo_retr(0, sd);
@@ -5535,7 +4902,7 @@ int pc_readparam(struct map_session_data *sd,int type)
if(val>=24 && val < 45)
val+=3978;
else
- val= sd->status.class;
+ val= sd->status.class_;
break;
case SP_BASEJOB:
val= s_class.job;
@@ -5594,6 +4961,12 @@ int pc_readparam(struct map_session_data *sd,int type)
case SP_LUK:
val= sd->status.luk;
break;
+ case SP_KARMA: // celest
+ val = sd->status.karma;
+ break;
+ case SP_MANNER:
+ val = sd->status.manner;
+ break;
case SP_FAME:
val= sd->fame;
break;
@@ -5613,7 +4986,7 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
nullpo_retr(0, sd);
- s_class = pc_calc_base_job(sd->status.class);
+ s_class = pc_calc_base_job(sd->status.class_);
switch(type){
case SP_BASELEVEL:
@@ -5627,24 +5000,27 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
clif_updatestatus(sd, SP_NEXTBASEEXP);
clif_updatestatus(sd, SP_STATUSPOINT);
clif_updatestatus(sd, SP_BASEEXP);
- pc_calcstatus(sd, 0);
+ status_calc_pc(sd, 0);
pc_heal(sd, sd->status.max_hp, sd->status.max_sp);
break;
case SP_JOBLEVEL:
- if (sd->status.class == 0)
+ if (s_class.job == 0)
up_level -= 40;
- if ((sd->status.class == 23) || (sd->status.class >= 4001 && sd->status.class <= 4022))
+ // super novices can go up to 99 [celest]
+ else if (s_class.job == 23)
+ up_level += 49;
+ else if (sd->status.class_ >= 4008 && sd->status.class_ <= 4022)
up_level += 20;
if (val >= sd->status.job_level) {
if (val > up_level)val = up_level;
sd->status.skill_point += (val-sd->status.job_level);
- sd->status.job_level = val;
+ sd->status.job_level = val;
sd->status.job_exp = 0;
clif_updatestatus(sd, SP_JOBLEVEL);
clif_updatestatus(sd, SP_NEXTJOBEXP);
clif_updatestatus(sd, SP_JOBEXP);
clif_updatestatus(sd, SP_SKILLPOINT);
- pc_calcstatus(sd, 0);
+ status_calc_pc(sd, 0);
clif_misceffect(&sd->bl, 1);
} else {
sd->status.job_level = val;
@@ -5652,7 +5028,7 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
clif_updatestatus(sd, SP_JOBLEVEL);
clif_updatestatus(sd, SP_NEXTJOBEXP);
clif_updatestatus(sd, SP_JOBEXP);
- pc_calcstatus(sd, 0);
+ status_calc_pc(sd, 0);
}
clif_updatestatus(sd,type);
break;
@@ -5663,7 +5039,21 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
sd->status.status_point = val;
break;
case SP_ZENY:
- sd->status.zeny = val;
+ if(val <= MAX_ZENY) {
+ // MAX_ZENY ˆÈ‰º‚È‚ç‘ã“ü
+ sd->status.zeny = val;
+ } else {
+ if(sd->status.zeny > val) {
+ // Zeny ‚ªŒ¸­‚µ‚Ä‚¢‚é‚È‚ç‘ã“ü
+ sd->status.zeny = val;
+ } else if(sd->status.zeny <= MAX_ZENY) {
+ // Zeny ‚ª‘‰Á‚µ‚Ä‚¢‚ÄAŒ»Ý‚Ì’l‚ªMAX_ZENY ˆÈ‰º‚È‚çMAX_ZENY
+ sd->status.zeny = MAX_ZENY;
+ } else {
+ // Zeny ‚ª‘‰Á‚µ‚Ä‚¢‚ÄAŒ»Ý‚Ì’l‚ªMAX_ZENY ‚æ‚艺‚Ȃ瑉Á•ª‚𖳎‹
+ ;
+ }
+ }
break;
case SP_BASEEXP:
if(pc_nextbaseexp(sd) > 0) {
@@ -5720,6 +5110,12 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
case SP_LUK:
sd->status.luk = val;
break;
+ case SP_KARMA:
+ sd->status.karma = val;
+ break;
+ case SP_MANNER:
+ sd->status.manner = val;
+ break;
case SP_FAME:
sd->fame = val;
break;
@@ -5749,7 +5145,7 @@ int pc_heal(struct map_session_data *sd,int hp,int sp)
sp = 0;
}
- if(sd->sc_data && sd->sc_data[SC_BERSERK].timer!=-1) //ƒo?ƒT?ƒN’†‚͉ñ•œ‚³‚¹‚È‚¢‚炵‚¢
+ if(sd->sc_count && sd->sc_data[SC_BERSERK].timer!=-1) //ƒo?ƒT?ƒN’†‚͉ñ•œ‚³‚¹‚È‚¢‚炵‚¢
return 0;
if(hp+sd->status.hp>sd->status.max_hp)
@@ -5784,13 +5180,13 @@ int pc_heal(struct map_session_data *sd,int hp,int sp)
*/
int pc_itemheal(struct map_session_data *sd,int hp,int sp)
{
- int bonus;
+ int bonus, type = 0;
// if(battle_config.battle_log)
// printf("heal %d %d\n",hp,sp);
nullpo_retr(0, sd);
- if(sd->sc_data && sd->sc_data[SC_GOSPEL].timer!=-1) //ƒo?ƒT?ƒN’†‚͉ñ•œ‚³‚¹‚È‚¢‚炵‚¢
+ if(sd->sc_count && sd->sc_data[SC_GOSPEL].timer!=-1) //ƒo?ƒT?ƒN’†‚͉ñ•œ‚³‚¹‚È‚¢‚炵‚¢
return 0;
if(sd->state.potionpitcher_flag) {
@@ -5807,19 +5203,33 @@ int pc_itemheal(struct map_session_data *sd,int hp,int sp)
if(sp > 0)
sp = 0;
}
+
+ if (sd->itemid >= 501 && sd->itemid <= 505)
+ type = 1; // potions
+ else if (sd->itemid >= 507 && sd->itemid <= 510)
+ type = 2; // herbs
+ else if (sd->itemid >= 512 && sd->itemid <= 516)
+ type = 3; // fruits
+ else if (sd->itemid == 517 || sd->itemid == 528)
+ type = 4; // meat
+ else if (sd->itemid == 529 || sd->itemid == 530)
+ type = 5; // candy
+ else if (sd->itemid >= 531 && sd->itemid <= 534)
+ type = 6; // juice
+ else if (sd->itemid == 544 || sd->itemid == 551)
+ type = 7; // sashimi
+
if(hp > 0) {
- bonus = (sd->paramc[2]<<1) + 100 + pc_checkskill(sd,SM_RECOVERY)*10;
- if(bonus != 100)
- hp = hp * bonus / 100;
- bonus = 100 + pc_checkskill(sd,AM_LEARNINGPOTION)*5;
+ bonus = (sd->paramc[2]<<1) + 100 + pc_checkskill(sd,SM_RECOVERY)*10
+ + pc_checkskill(sd,AM_LEARNINGPOTION)*5;
+ if (type > 0)
+ bonus += sd->itemhealrate[type - 1];
if(bonus != 100)
hp = hp * bonus / 100;
}
if(sp > 0) {
- bonus = (sd->paramc[3]<<1) + 100 + pc_checkskill(sd,MG_SRECOVERY)*10;
- if(bonus != 100)
- sp = sp * bonus / 100;
- bonus = 100 + pc_checkskill(sd,AM_LEARNINGPOTION)*5;
+ bonus = (sd->paramc[3]<<1) + 100 + pc_checkskill(sd,MG_SRECOVERY)*10
+ + pc_checkskill(sd,AM_LEARNINGPOTION)*5;
if(bonus != 100)
sp = sp * bonus / 100;
}
@@ -5920,13 +5330,13 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
int i;
int b_class = 0;
//?¶‚â—{Žq‚Ìꇂ̌³‚ÌE‹Æ‚ðŽZo‚·‚é
- struct pc_base_job s_class = pc_calc_base_job(sd->status.class);
-
+ struct pc_base_job s_class = pc_calc_base_job(sd->status.class_);
+
nullpo_retr(0, sd);
if (upper < 0 || upper > 2) //Œ»Ý?¶‚©‚Ç‚¤‚©‚ð”»?‚·‚é
upper = s_class.upper;
-
+
b_class = job; //’ÊíE‚È‚çjob‚»‚̂܂ñ‚Ü
if (job < 23) {
if (upper == 1)
@@ -5948,7 +5358,7 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
if((sd->status.sex == 0 && job == 19) || (sd->status.sex == 1 && job == 20) ||
// not needed [celest]
//(sd->status.sex == 0 && job == 4020) || (sd->status.sex == 1 && job == 4021) ||
- job == 22 || sd->status.class == b_class) //Š‚Íƒo?ƒh‚ɂȂê‚È‚¢A‰‚̓_ƒ“ƒT?‚ɂȂê‚È‚¢AŒ‹¥ˆßÖ‚à‚¨?‚è
+ job == 22 || sd->status.class_ == b_class) //Š‚Íƒo?ƒh‚ɂȂê‚È‚¢A‰‚̓_ƒ“ƒT?‚ɂȂê‚È‚¢AŒ‹¥ˆßÖ‚à‚¨?‚è
return 1;
// check if we are changing from 1st to 2nd job
@@ -5958,12 +5368,12 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
else
sd->change_level = 40;
}
- else
- sd->change_level = 0;
+ else
+ sd->change_level = 0;
- pc_setglobalreg (sd, "jobchange_level", sd->change_level);
-
- sd->status.class = sd->view_class = b_class;
+ pc_setglobalreg (sd, "jobchange_level", sd->change_level);
+
+ sd->status.class_ = sd->view_class = b_class;
sd->status.job_level=1;
sd->status.job_exp=0;
@@ -5974,7 +5384,7 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
for(i=0;i<11;i++) {
if(sd->equip_index[i] >= 0)
if(!pc_isequip(sd,sd->equip_index[i]))
- pc_unequipitem(sd,sd->equip_index[i],1,BF_NORMAL); // ?”õŠO‚µ
+ pc_unequipitem(sd,sd->equip_index[i],2); // ?”õŠO‚µ
}
clif_changelook(&sd->bl,LOOK_BASE,sd->view_class); // move sprite update to prevent client crashes with incompatible equipment [Valaris]
@@ -5983,18 +5393,18 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
if(battle_config.muting_players && sd->status.manner < 0)
clif_changestatus(&sd->bl,SP_MANNER,sd->status.manner);
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
pc_checkallowskill(sd);
pc_equiplookall(sd);
clif_equiplist(sd);
if(pc_isriding(sd)) { // remove peco status if changing into invalid class [Valaris]
- if(!(pc_checkskill(sd,KN_RIDING)))
+ if(!(pc_checkskill(sd,KN_RIDING)))
pc_setoption(sd,sd->status.option|-0x0000);
if(pc_checkskill(sd,KN_RIDING)>0)
pc_setriding(sd);
}
-
+
return 0;
}
@@ -6071,7 +5481,7 @@ int pc_setoption(struct map_session_data *sd,int type)
sd->status.option=type;
clif_changeoption(&sd->bl);
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
return 0;
}
@@ -6129,23 +5539,35 @@ int pc_setriding(struct map_session_data *sd)
if((pc_checkskill(sd,KN_RIDING)>0)){ // ƒ‰ƒCƒfƒBƒ“ƒOƒXƒLƒ‹ŠŽ
pc_setoption(sd,sd->status.option|0x0020);
- if(sd->status.class==7)
- sd->status.class=sd->view_class=13;
-
- if(sd->status.class==14)
- sd->status.class=sd->view_class=21;
-
- if(sd->status.class==4008)
- sd->status.class=sd->view_class=4014;
-
- if(sd->status.class==4015)
- sd->status.class=sd->view_class=4022;
+ if(sd->status.class_==7)
+ sd->status.class_=sd->view_class=13;
+
+ if(sd->status.class_==14)
+ sd->status.class_=sd->view_class=21;
+
+ if(sd->status.class_==4008)
+ sd->status.class_=sd->view_class=4014;
+
+ if(sd->status.class_==4015)
+ sd->status.class_=sd->view_class=4022;
}
return 0;
}
/*==========================================
+ * ƒAƒCƒeƒ€ƒhƒƒbƒv‰Â•s‰Â”»’è
+ *------------------------------------------
+ */
+int pc_candrop(struct map_session_data *sd,int item_id)
+{
+ int level;
+ if((level=pc_isGM(sd))>0 && level < battle_config.gm_can_drop_lv) // search only once [Celest]
+ return 1;
+ return 0;
+}
+
+/*==========================================
* script—p??‚Ì’l‚ð?‚Þ
*------------------------------------------
*/
@@ -6178,14 +5600,7 @@ int pc_setreg(struct map_session_data *sd,int reg,int val)
}
}
sd->reg_num++;
- sd->reg = realloc(sd->reg, sizeof(*(sd->reg)) * sd->reg_num);
- if (sd->reg == NULL){
- printf("out of memory : pc_setreg\n");
- exit(1);
- }
-/* memset(sd->reg + (sd->reg_num - 1) * sizeof(*(sd->reg)), 0,
- sizeof(*(sd->reg)));
-*/
+ sd->reg = (struct script_reg *) aRealloc(sd->reg, sizeof(*(sd->reg)) * sd->reg_num);
sd->reg[i].index = reg;
sd->reg[i].data = val;
@@ -6229,7 +5644,7 @@ int pc_setregstr(struct map_session_data *sd,int reg,char *str)
return 0;
}
sd->regstr_num++;
- sd->regstr = realloc(sd->regstr, sizeof(sd->regstr[0]) * sd->regstr_num);
+ sd->regstr = (struct script_regstr *) aRealloc(sd->regstr, sizeof(sd->regstr[0]) * sd->regstr_num);
if(sd->regstr==NULL){
printf("out of memory : pc_setreg\n");
exit(1);
@@ -6271,11 +5686,18 @@ int pc_setglobalreg(struct map_session_data *sd,char *reg,int val)
nullpo_retr(0, sd);
- //PC_DIE_COUNTER‚ªƒXƒNƒŠƒvƒg‚ȂǂÅ?X‚³‚ê‚½Žž‚Ì?—
+ //PC_DIE_COUNTER‚ªƒXƒNƒŠƒvƒg‚ȂǂÅ?X‚³‚ꂽŽbÌ?—
if(strcmp(reg,"PC_DIE_COUNTER") == 0 && sd->die_counter != val){
sd->die_counter = val;
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
+ } else if(strcmp(reg,script_config.die_event_name) == 0){
+ sd->state.event_death = val;
+ } else if(strcmp(reg,script_config.kill_event_name) == 0){
+ sd->state.event_kill = val;
+ } else if(strcmp(reg,script_config.logout_event_name) == 0){
+ sd->state.event_disconnect = val;
}
+
if(val==0){
for(i=0;i<sd->status.global_reg_num;i++){
if(strcmp(sd->status.global_reg[i].str,reg)==0){
@@ -6331,6 +5753,12 @@ int pc_setaccountreg(struct map_session_data *sd,char *reg,int val)
nullpo_retr(0, sd);
+ if (sd->status.account_reg_num == -1) {
+ if(battle_config.error_log)
+ printf("pc_setaccountreg : refusing to set until vars are received\n");
+ return 1;
+ }
+
if(val==0){
for(i=0;i<sd->status.account_reg_num;i++){
if(strcmp(sd->status.account_reg[i].str,reg)==0){
@@ -6418,29 +5846,6 @@ int pc_setaccountreg2(struct map_session_data *sd,char *reg,int val)
return 1;
}
-/*==========================================
- * ¸?¬Œ÷—¦
- *------------------------------------------
- */
-int pc_percentrefinery(struct map_session_data *sd,struct item *item)
-{
- int percent;
-
- nullpo_retr(0, item);
- percent=percentrefinery[itemdb_wlv(item->nameid)][(int)item->refine];
-
- percent += pc_checkskill(sd,BS_WEAPONRESEARCH); // •Ší?‹†ƒXƒLƒ‹ŠŽ
-
- // Šm—¦‚Ì—L?”Í?ƒ`ƒFƒbƒN
- if( percent > 100 ){
- percent = 100;
- }
- if( percent < 0 ){
- percent = 0;
- }
-
- return percent;
-}
/*==========================================
* ƒCƒxƒ“ƒgƒ^ƒCƒ}??—
@@ -6449,6 +5854,7 @@ int pc_percentrefinery(struct map_session_data *sd,struct item *item)
int pc_eventtimer(int tid,unsigned int tick,int id,int data)
{
struct map_session_data *sd=map_id2sd(id);
+ char *p = (char *)data;
int i;
if(sd==NULL)
return 0;
@@ -6456,11 +5862,11 @@ int pc_eventtimer(int tid,unsigned int tick,int id,int data)
for(i=0;i<MAX_EVENTTIMER;i++){
if( sd->eventtimer[i]==tid ){
sd->eventtimer[i]=-1;
- npc_event(sd,(const char *)data,0);
+ npc_event(sd,p,0);
break;
}
}
- free((void *)data);
+ aFree(p);
if(i==MAX_EVENTTIMER) {
if(battle_config.error_log)
printf("pc_eventtimer: no such event timer\n");
@@ -6483,10 +5889,12 @@ int pc_addeventtimer(struct map_session_data *sd,int tick,const char *name)
if( sd->eventtimer[i]==-1 )
break;
if(i<MAX_EVENTTIMER){
- char *evname=(char *)aCalloc(24,sizeof(char));
- memcpy(evname,name,24);
+ char *evname=strdup(name);
+ //char *evname=(char *)aMallocA((strlen(name)+1)*sizeof(char));
+ //memcpy(evname,name,(strlen(name)+1));
sd->eventtimer[i]=add_timer(gettick()+tick,
pc_eventtimer,sd->bl.id,(int)evname);
+ sd->eventcount++;
}
return 0;
@@ -6502,12 +5910,19 @@ int pc_deleventtimer(struct map_session_data *sd,const char *name)
nullpo_retr(0, sd);
+ if (sd->eventcount <= 0)
+ return 0;
+
for(i=0;i<MAX_EVENTTIMER;i++)
- if( sd->eventtimer[i]!=-1 && strcmp(
- (char *)(get_timer(sd->eventtimer[i])->data), name)==0 ){
+ if( sd->eventtimer[i]!=-1 ) {
+ char *p = (char *)(get_timer(sd->eventtimer[i])->data);
+ if(strcmp(p, name)==0) {
delete_timer(sd->eventtimer[i],pc_eventtimer);
sd->eventtimer[i]=-1;
+ sd->eventcount--;
+ aFree(p);
break;
+ }
}
return 0;
@@ -6543,10 +5958,15 @@ int pc_cleareventtimer(struct map_session_data *sd)
nullpo_retr(0, sd);
+ if (sd->eventcount <= 0)
+ return 0;
+
for(i=0;i<MAX_EVENTTIMER;i++)
if( sd->eventtimer[i]!=-1 ){
+ char *p = (char *)(get_timer(sd->eventtimer[i])->data);
delete_timer(sd->eventtimer[i],pc_eventtimer);
sd->eventtimer[i]=-1;
+ aFree(p);
}
return 0;
@@ -6579,7 +5999,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int pos)
// -- moonsoul (if player is berserk then cannot equip)
//
- if(sd->sc_data[SC_BERSERK].timer!=-1){
+ if(sd->sc_count && sd->sc_data[SC_BERSERK].timer!=-1){
clif_equipitemack(sd,n,0,0); // fail
return 0;
}
@@ -6597,7 +6017,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int pos)
// “ñ“—¬?—
if ((pos==0x22) // ˆê?A?”õ—v‹‰ÓŠ‚ª“ñ“—¬•Ší‚©ƒ`ƒFƒbƒN‚·‚é
&& (id->equip==2) // ? Žè•Ší
- && (pc_checkskill(sd, AS_LEFT) > 0 || pc_calc_base_job2(sd->status.class) == 12) ) // ¶ŽèC?—L
+ && (pc_checkskill(sd, AS_LEFT) > 0 || pc_calc_base_job2(sd->status.class_) == 12) ) // ¶ŽèC?—L
{
int tpos=0;
if(sd->equip_index[8] >= 0)
@@ -6611,7 +6031,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int pos)
arrow=pc_search_inventory(sd,pc_checkequip(sd,9)); // Added by RoVeRT
for(i=0;i<11;i++) {
if(sd->equip_index[i] >= 0 && sd->status.inventory[sd->equip_index[i]].equip&pos) {
- pc_unequipitem(sd,sd->equip_index[i],1,BF_NORMAL);
+ pc_unequipitem(sd,sd->equip_index[i],2);
}
}
// ‹|–î?”õ
@@ -6680,40 +6100,47 @@ int pc_equipitem(struct map_session_data *sd,int n,int pos)
clif_changelook(&sd->bl,LOOK_SHOES,0);
pc_checkallowskill(sd); // ?”õ•i‚ŃXƒLƒ‹‚©‰ðœ‚³‚ê‚é‚©ƒ`ƒFƒbƒN
- if (itemdb_look(sd->status.inventory[n].nameid) == 11 && arrow){ // Added by RoVeRT
+ if (itemdb_look(sd->status.inventory[n].nameid) == 11 && (arrow >= 0)){ // Added by RoVeRT
clif_arrowequip(sd,arrow);
sd->status.inventory[arrow].equip=32768;
}
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
if(sd->special_state.infinite_endure) {
if(sd->sc_data[SC_ENDURE].timer == -1)
- skill_status_change_start(&sd->bl,SC_ENDURE,10,1,0,0,0,0);
+ status_change_start(&sd->bl,SC_ENDURE,10,1,0,0,0,0);
}
else {
- if(sd->sc_data[SC_ENDURE].timer != -1 && sd->sc_data[SC_ENDURE].val2)
- skill_status_change_end(&sd->bl,SC_ENDURE,-1);
+ if(sd->sc_count && sd->sc_data[SC_ENDURE].timer != -1 && sd->sc_data[SC_ENDURE].val2)
+ status_change_end(&sd->bl,SC_ENDURE,-1);
}
- if(sd->sc_data[SC_SIGNUMCRUCIS].timer != -1 && !battle_check_undead(7,sd->def_ele))
- skill_status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1);
- if(sd->sc_data[SC_DANCING].timer!=-1 && (sd->status.weapon != 13 && sd->status.weapon !=14))
- skill_stop_dancing(&sd->bl,0);
+ if(sd->sc_count) {
+ if (sd->sc_data[SC_SIGNUMCRUCIS].timer != -1 && !battle_check_undead(7,sd->def_ele))
+ status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1);
+ if(sd->sc_data[SC_DANCING].timer!=-1 && (sd->status.weapon != 13 && sd->status.weapon !=14))
+ skill_stop_dancing(&sd->bl,0);
+ }
return 0;
}
/*==========================================
* ? ”õ‚µ‚½•¨‚ðŠO‚·
+ * type:
+ * 0 - only unequip
+ * 1 - calculate status after unequipping
+ * 2 - force unequip
*------------------------------------------
*/
-int pc_unequipitem(struct map_session_data *sd,int n,int type, int flag)
+int pc_unequipitem(struct map_session_data *sd,int n,int flag)
{
- nullpo_retr(0, sd);
+ short hp = 0, sp = 0;
+ nullpo_retr(0, sd);
// -- moonsoul (if player is berserk then cannot unequip)
//
- if(!flag && sd->sc_data[SC_BERSERK].timer!=-1){
+ if(flag<2 && sd->sc_count && (sd->sc_data[SC_BLADESTOP].timer!=-1 || sd->sc_data[SC_BERSERK].timer!=-1)){
clif_unequipitemack(sd,n,0,0);
return 0;
}
@@ -6723,8 +6150,17 @@ int pc_unequipitem(struct map_session_data *sd,int n,int type, int flag)
if(sd->status.inventory[n].equip){
int i;
for(i=0;i<11;i++) {
- if(sd->status.inventory[n].equip & equip_pos[i])
+ if(sd->status.inventory[n].equip & equip_pos[i]) {
sd->equip_index[i] = -1;
+ if(sd->unequip_losehp[i] > 0) {
+ hp += sd->unequip_losehp[i];
+ sd->unequip_losehp[i] = 0;
+ }
+ if(sd->unequip_losesp[i] > 0) {
+ sp += sd->unequip_losesp[i];
+ sd->unequip_losesp[i] = 0;
+ }
+ }
}
if(sd->status.inventory[n].equip & 0x0002) {
sd->weapontype1 = 0;
@@ -6752,23 +6188,37 @@ int pc_unequipitem(struct map_session_data *sd,int n,int type, int flag)
if(sd->status.inventory[n].equip & 0x0040)
clif_changelook(&sd->bl,LOOK_SHOES,0);
- if(sd->sc_data[SC_BROKNWEAPON].timer != -1 && sd->status.inventory[n].equip & 0x0002 &&
- sd->status.inventory[i].attribute==1)
- skill_status_change_end(&sd->bl,SC_BROKNWEAPON,-1);
+ if(sd->sc_count) {
+ if (sd->sc_data[SC_BROKNWEAPON].timer != -1 && sd->status.inventory[n].equip & 0x0002 &&
+ sd->status.inventory[n].attribute == 1)
+ status_change_end(&sd->bl,SC_BROKNWEAPON,-1);
+ if(sd->sc_data[SC_BROKNARMOR].timer != -1 && sd->status.inventory[n].equip & 0x0010 &&
+ sd->status.inventory[n].attribute == 1)
+ status_change_end(&sd->bl,SC_BROKNARMOR,-1);
+ }
clif_unequipitemack(sd,n,sd->status.inventory[n].equip,1);
sd->status.inventory[n].equip=0;
- if(!type)
+ if(flag&1)
pc_checkallowskill(sd);
if(sd->weapontype1 == 0 && sd->weapontype2 == 0)
- skill_encchant_eremental_end(&sd->bl,-1); //•ŠíŽ‚¿¾‚¦‚Í–³?Œ‚Å?«•t?‰ðœ
+ skill_enchant_elemental_end(&sd->bl,-1); //•ŠíŽ‚¿¾‚¦‚Í–³?Œ‚Å?«•t?‰ðœ
} else {
clif_unequipitemack(sd,n,0,0);
}
- if(!type) {
- pc_calcstatus(sd,0);
- if(sd->sc_data[SC_SIGNUMCRUCIS].timer != -1 && !battle_check_undead(7,sd->def_ele))
- skill_status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1);
+
+ if(flag&1) {
+ status_calc_pc(sd,0);
+ if(sd->sc_count && sd->sc_data[SC_SIGNUMCRUCIS].timer != -1 && !battle_check_undead(7,sd->def_ele))
+ status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1);
+ }
+
+ if (hp > 0 || sp > 0) {
+ if (hp > sd->status.hp)
+ hp = sd->status.hp;
+ if (sp > sd->status.sp)
+ sp = sd->status.sp;
+ pc_heal(sd,-hp,-sp);
}
return 0;
@@ -6838,10 +6288,10 @@ int pc_checkitem(struct map_session_data *sd)
calc_flag = 1;
}
//?”õ§ŒÀƒ`ƒFƒbƒN
- if(sd->status.inventory[i].equip && map[sd->bl.m].flag.pvp && (it->flag.no_equip==1 || it->flag.no_equip==3)){//PvP§ŒÀ
+ if(sd->status.inventory[i].equip && map[sd->bl.m].flag.pvp && (it->flag.no_equip&1)){//PVP check for forbiden items. optimized by [Lupus]
sd->status.inventory[i].equip=0;
calc_flag = 1;
- }else if(sd->status.inventory[i].equip && map[sd->bl.m].flag.gvg && (it->flag.no_equip==2 || it->flag.no_equip==3)){//GvG§ŒÀ
+ }else if(sd->status.inventory[i].equip && map[sd->bl.m].flag.gvg && (it->flag.no_equip>1)){//GvG optimized by [Lupus]
sd->status.inventory[i].equip=0;
calc_flag = 1;
}
@@ -6849,7 +6299,7 @@ int pc_checkitem(struct map_session_data *sd)
pc_setequipindex(sd);
if(calc_flag)
- pc_calcstatus(sd,2);
+ status_calc_pc(sd,2);
return 0;
}
@@ -6912,7 +6362,7 @@ int pc_calc_pvprank(struct map_session_data *sd)
nullpo_retr(0, sd);
nullpo_retr(0, m=&map[sd->bl.m]);
-
+
old=sd->pvp_rank;
if( !(m->flag.pvp) )
@@ -6958,12 +6408,12 @@ int pc_ismarried(struct map_session_data *sd)
return 0;
}
/*==========================================
- * sd‚ªdstsd‚ÆŒ‹¥(dstsd¨sd‚ÌŒ‹¥?—‚à“¯Žž‚És‚¤)
+ * sd‚ªdstsd‚ÆŒ‹¥(dstsd¨sd‚ÌŒ‹¥?—‚à“¯ŽbÉs‚¤)
*------------------------------------------
*/
int pc_marriage(struct map_session_data *sd,struct map_session_data *dstsd)
{
- if(sd == NULL || dstsd == NULL || sd->status.partner_id > 0 || dstsd->status.partner_id > 0 || pc_calc_upper(sd->status.class)==2)
+ if(sd == NULL || dstsd == NULL || sd->status.partner_id > 0 || dstsd->status.partner_id > 0 || pc_calc_upper(sd->status.class_)==2)
return -1;
sd->status.partner_id=dstsd->status.char_id;
dstsd->status.partner_id=sd->status.char_id;
@@ -6971,7 +6421,7 @@ int pc_marriage(struct map_session_data *sd,struct map_session_data *dstsd)
}
/*==========================================
- * sd‚ª—£¥(‘ŠŽè‚Ísd->status.partner_id‚Ɉ˂é)(‘ŠŽè‚à“¯Žž‚É—£¥?Œ‹¥Žw—ÖŽ©“®?’D)
+ * sd‚ª—£¥(‘ŠŽè‚Ísd->status.partner_id‚Ɉ˂é)(‘ŠŽè‚à“¯ŽbÉ—£¥?Œ‹¥Žw—ÖŽ©“®?’D)
*------------------------------------------
*/
int pc_divorce(struct map_session_data *sd)
@@ -7003,25 +6453,78 @@ int pc_divorce(struct map_session_data *sd)
}
/*==========================================
+ * sd - father dstsd - mother jasd - child
+ */
+int pc_adoption(struct map_session_data *sd,struct map_session_data *dstsd, struct map_session_data *jasd)
+{
+ int j;
+ if(sd == NULL || dstsd == NULL || jasd == NULL || sd->status.partner_id <= 0 || dstsd->status.partner_id <= 0 || sd->status.partner_id != dstsd->status.char_id || dstsd->status.partner_id != sd->status.char_id || sd->status.child > 0 || dstsd->status.child || jasd->status.father > 0 || jasd->status.mother > 0)
+ return -1;
+ jasd->status.father=sd->status.char_id;
+ jasd->status.mother=dstsd->status.char_id;
+ sd->status.child=jasd->status.char_id;
+ dstsd->status.child=jasd->status.char_id;
+ for (j=0; j < MAX_INVENTORY; j++) {
+ if(jasd->status.inventory[j].nameid>0 && jasd->status.inventory[j].equip!=0)
+ pc_unequipitem(jasd, j, 3);
+ }
+ if (pc_jobchange(jasd, 4023, 0) == 0)
+ clif_displaymessage(jasd->fd, msg_table[12]); // Your job has been changed.
+ else {
+ clif_displaymessage(jasd->fd, msg_table[155]); // Impossible to change your job.
+ return -1;
+ }
+ return 0;
+}
+
+/*==========================================
* sd‚Ì‘Š•û‚Ìmap_session_data‚ð•Ô‚·
*------------------------------------------
*/
struct map_session_data *pc_get_partner(struct map_session_data *sd)
{
- struct map_session_data *p_sd = NULL;
- char *nick;
- if(sd == NULL || !pc_ismarried(sd))
- return NULL;
+ //struct map_session_data *p_sd = NULL;
+ //char *nick;
+ //if(sd == NULL || !pc_ismarried(sd))
+ // return NULL;
+ //nick=map_charid2nick(sd->status.partner_id);
+ //if (nick==NULL)
+ // return NULL;
+ //if((p_sd=map_nick2sd(nick)) == NULL )
+ // return NULL;
- nick=map_charid2nick(sd->status.partner_id);
+ if (sd && pc_ismarried(sd))
+ // charid2sd returns NULL if not found
+ return map_charid2sd(sd->status.partner_id);
- if (nick==NULL)
- return NULL;
+ return NULL;
+}
- if((p_sd=map_nick2sd(nick)) == NULL )
- return NULL;
+struct map_session_data *pc_get_father (struct map_session_data *sd)
+{
+ if (sd && pc_calc_upper(sd->status.class_) == 2 && sd->status.father > 0)
+ // charid2sd returns NULL if not found
+ return map_charid2sd(sd->status.father);
- return p_sd;
+ return NULL;
+}
+
+struct map_session_data *pc_get_mother (struct map_session_data *sd)
+{
+ if (sd && pc_calc_upper(sd->status.class_) == 2 && sd->status.mother > 0)
+ // charid2sd returns NULL if not found
+ return map_charid2sd(sd->status.mother);
+
+ return NULL;
+}
+
+struct map_session_data *pc_get_child (struct map_session_data *sd)
+{
+ if (sd && pc_ismarried(sd) && sd->status.child > 0)
+ // charid2sd returns NULL if not found
+ return map_charid2sd(sd->status.child);
+
+ return NULL;
}
//
@@ -7054,8 +6557,8 @@ static int pc_spheal(struct map_session_data *sd)
if(gc) {
struct guild *g;
g=guild_search(sd->status.guild_id);
- if(g && g->guild_id == gc->guild_id)
- a += a;
+ if(g && g->guild_id == gc->guild_id)
+ a += a;
} // end addition [Valaris]
return a;
@@ -7084,8 +6587,8 @@ static int pc_hpheal(struct map_session_data *sd)
if(gc) {
struct guild *g;
g=guild_search(sd->status.guild_id);
- if(g && g->guild_id == gc->guild_id)
- a += a;
+ if(g && g->guild_id == gc->guild_id)
+ a += a;
} // end addition [Valaris]
return a;
@@ -7098,7 +6601,10 @@ static int pc_natural_heal_hp(struct map_session_data *sd)
nullpo_retr(0, sd);
- if (sd->sc_data[SC_TRICKDEAD].timer != -1) // Modified by RoVeRT
+ if (sd->sc_count && sd->sc_data[SC_TRICKDEAD].timer != -1) // Modified by RoVeRT
+ return 0;
+
+ if (sd->no_regen & 1)
return 0;
if(pc_checkoverhp(sd)) {
@@ -7111,11 +6617,11 @@ static int pc_natural_heal_hp(struct map_session_data *sd)
if(sd->walktimer == -1) {
inc_num = pc_hpheal(sd);
- if( sd->sc_data[SC_TENSIONRELAX].timer!=-1 ){ // ƒeƒ“ƒVƒ‡ƒ“ƒŠƒ‰ƒbƒNƒX
+ if(sd->sc_data[SC_TENSIONRELAX].timer!=-1 ){ // ƒeƒ“ƒVƒ‡ƒ“ƒŠƒ‰ƒbƒNƒX
sd->hp_sub += 2*inc_num;
sd->inchealhptick += 3*natural_heal_diff_tick;
- }else{
- sd->hp_sub += inc_num;
+ } else {
+ sd->hp_sub += inc_num;
sd->inchealhptick += natural_heal_diff_tick;
}
}
@@ -7168,7 +6674,7 @@ static int pc_natural_heal_hp(struct map_session_data *sd)
return 0;
- if(sd->sc_data[SC_APPLEIDUN].timer!=-1) { // Apple of Idun
+ if(sd->sc_count && sd->sc_data[SC_APPLEIDUN].timer!=-1 && sd->sc_data[SC_BERSERK].timer==-1) { // Apple of Idun
if(sd->inchealhptick >= 6000 && sd->status.hp < sd->status.max_hp) {
bonus = skill*20;
while(sd->inchealhptick >= 6000) {
@@ -7196,8 +6702,12 @@ static int pc_natural_heal_sp(struct map_session_data *sd)
nullpo_retr(0, sd);
- if (sd->sc_data[SC_TRICKDEAD].timer != -1 || // Modified by RoVeRT
- sd->sc_data[SC_BERSERK].timer != -1)
+ if (sd->sc_count && (sd->sc_data[SC_TRICKDEAD].timer != -1 || // Modified by RoVeRT
+ sd->sc_data[SC_BERSERK].timer != -1 ||
+ sd->sc_data[SC_BLEEDING].timer != -1))
+ return 0;
+
+ if (sd->no_regen & 2)
return 0;
if(pc_checkoversp(sd)) {
@@ -7232,7 +6742,7 @@ static int pc_natural_heal_sp(struct map_session_data *sd)
if(sd->nshealsp > 0) {
if(sd->inchealsptick >= battle_config.natural_heal_skill_interval && sd->status.sp < sd->status.max_sp) {
- struct pc_base_job s_class = pc_calc_base_job(sd->status.class);
+ struct pc_base_job s_class = pc_calc_base_job(sd->status.class_);
if(sd->doridori_counter && s_class.job == 23)
bonus = sd->nshealsp*2;
else
@@ -7256,7 +6766,7 @@ static int pc_natural_heal_sp(struct map_session_data *sd)
return 0;
}
-static int pc_spirit_heal_hp(struct map_session_data *sd,int level)
+static int pc_spirit_heal_hp(struct map_session_data *sd)
{
int bonus_hp,interval = battle_config.natural_heal_skill_interval;
@@ -7296,7 +6806,7 @@ static int pc_spirit_heal_hp(struct map_session_data *sd,int level)
return 0;
}
-static int pc_spirit_heal_sp(struct map_session_data *sd,int level)
+static int pc_spirit_heal_sp(struct map_session_data *sd)
{
int bonus_sp,interval = battle_config.natural_heal_skill_interval;
@@ -7337,6 +6847,30 @@ static int pc_spirit_heal_sp(struct map_session_data *sd,int level)
return 0;
}
+static int pc_bleeding (struct map_session_data *sd)
+{
+ int interval, hp;
+
+ nullpo_retr(0, sd);
+ interval = sd->hp_loss_rate;
+ hp = sd->hp_loss_value;
+
+ sd->hp_loss_tick += natural_heal_diff_tick;
+ if(sd->hp_loss_tick >= interval) {
+ while(sd->hp_loss_tick >= interval) {
+ sd->hp_loss_tick -= interval;
+ if (sd->status.hp < hp)
+ hp = sd->status.hp;
+ if (sd->hp_loss_type == 1) {
+ clif_damage(&sd->bl,&sd->bl,gettick(),0,0,hp,0,0,0);
+ }
+ pc_heal(sd,-hp,0);
+ sd->hp_loss_tick = 0;
+ }
+ }
+ return 0;
+}
+
/*==========================================
* HP/SP Ž©‘R‰ñ•œ ŠeƒNƒ‰ƒCƒAƒ“ƒg
*------------------------------------------
@@ -7344,33 +6878,43 @@ static int pc_spirit_heal_sp(struct map_session_data *sd,int level)
static int pc_natural_heal_sub(struct map_session_data *sd,va_list ap) {
int skill;
+ int tick;
nullpo_retr(0, sd);
+ tick = va_arg(ap,int);
// -- moonsoul (if conditions below altered to disallow natural healing if under berserk status)
if ((battle_config.natural_heal_weight_rate > 100 || sd->weight*100/sd->max_weight < battle_config.natural_heal_weight_rate) &&
- !pc_isdead(sd) &&
- !pc_ishiding(sd) &&
- !(sd->sc_data[SC_POISON].timer != -1 && sd->sc_data[SC_SLOWPOISON].timer == -1) &&
- sd->sc_data[SC_BERSERK].timer == -1 ) {
+ !pc_isdead(sd) &&
+ !pc_ishiding(sd) &&
+ //-- cannot regen for 5 minutes after using Berserk --- [Celest]
+ DIFF_TICK (tick, sd->canregen_tick)>=0 &&
+ (sd->sc_data && !(sd->sc_data[SC_POISON].timer != -1 && sd->sc_data[SC_SLOWPOISON].timer == -1) &&
+ sd->sc_data[SC_BERSERK].timer == -1 )) {
pc_natural_heal_hp(sd);
if( sd->sc_data && sd->sc_data[SC_EXTREMITYFIST].timer == -1 && //ˆ¢C—…?‘Ô‚Å‚ÍSP‚ª‰ñ•œ‚µ‚È‚¢
sd->sc_data[SC_DANCING].timer == -1 && //ƒ_ƒ“ƒX?‘Ô‚Å‚ÍSP‚ª‰ñ•œ‚µ‚È‚¢
sd->sc_data[SC_BERSERK].timer == -1 ) //ƒo?ƒT?ƒN?‘Ô‚Å‚ÍSP‚ª‰ñ•œ‚µ‚È‚¢
pc_natural_heal_sp(sd);
+ sd->canregen_tick = tick;
} else {
sd->hp_sub = sd->inchealhptick = 0;
sd->sp_sub = sd->inchealsptick = 0;
}
if((skill = pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0 && !pc_ishiding(sd) &&
sd->sc_data[SC_POISON].timer == -1 && sd->sc_data[SC_BERSERK].timer == -1){
- pc_spirit_heal_hp(sd,skill);
- pc_spirit_heal_sp(sd,skill);
+ pc_spirit_heal_hp(sd);
+ pc_spirit_heal_sp(sd);
}
else {
sd->inchealspirithptick = 0;
sd->inchealspiritsptick = 0;
}
+ if (sd->hp_loss_value > 0)
+ pc_bleeding(sd);
+ else
+ sd->hp_loss_tick = 0;
+
return 0;
}
@@ -7382,7 +6926,7 @@ int pc_natural_heal(int tid,unsigned int tick,int id,int data)
{
natural_heal_tick = tick;
natural_heal_diff_tick = DIFF_TICK(natural_heal_tick,natural_heal_prev_tick);
- clif_foreachclient(pc_natural_heal_sub);
+ clif_foreachclient(pc_natural_heal_sub, tick);
natural_heal_prev_tick = tick;
return 0;
@@ -7412,9 +6956,10 @@ static int pc_autosave_sub(struct map_session_data *sd,va_list ap)
{
nullpo_retr(0, sd);
- if(save_flag==0 && sd->fd>last_save_fd){
- struct guild_castle *gc=NULL;
- int i;
+ Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
+
+ if(save_flag==0 && sd->fd>last_save_fd && !sd->state.waitingdisconnect){
+
// if(battle_config.save_log)
// printf("autosave %d\n",sd->fd);
// pet
@@ -7424,19 +6969,6 @@ static int pc_autosave_sub(struct map_session_data *sd,va_list ap)
chrif_save(sd);
storage_storage_save(sd);
- for(i=0;i<MAX_GUILDCASTLE;i++){
- gc=guild_castle_search(i);
- if(!gc) continue;
- if(gc->visibleG0==1) guild_castledatasave(gc->castle_id,18,gc->Ghp0);
- if(gc->visibleG1==1) guild_castledatasave(gc->castle_id,19,gc->Ghp1);
- if(gc->visibleG2==1) guild_castledatasave(gc->castle_id,20,gc->Ghp2);
- if(gc->visibleG3==1) guild_castledatasave(gc->castle_id,21,gc->Ghp3);
- if(gc->visibleG4==1) guild_castledatasave(gc->castle_id,22,gc->Ghp4);
- if(gc->visibleG5==1) guild_castledatasave(gc->castle_id,23,gc->Ghp5);
- if(gc->visibleG6==1) guild_castledatasave(gc->castle_id,24,gc->Ghp6);
- if(gc->visibleG7==1) guild_castledatasave(gc->castle_id,25,gc->Ghp7);
- }
-
save_flag=1;
last_save_fd = sd->fd;
}
@@ -7471,10 +7003,10 @@ int pc_read_gm_account(int fd)
int i = 0;
#endif
if (gm_account != NULL)
- free(gm_account);
+ aFree(gm_account);
GM_num = 0;
#ifdef TXT_ONLY
- gm_account = calloc(sizeof(struct gm_account) * ((RFIFOW(fd,2) - 4) / 5), 1);
+ gm_account = (struct gm_account *) aCallocA(sizeof(struct gm_account) * ((RFIFOW(fd,2) - 4) / 5), 1);
for (i = 4; i < RFIFOW(fd,2); i = i + 5) {
gm_account[GM_num].account_id = RFIFOL(fd,i);
gm_account[GM_num].level = (int)RFIFOB(fd,i+4);
@@ -7488,7 +7020,7 @@ int pc_read_gm_account(int fd)
}
lsql_res = mysql_store_result(&lmysql_handle);
if (lsql_res) {
- gm_account = calloc(sizeof(struct gm_account) * mysql_num_rows(lsql_res), 1);
+ gm_account = (struct gm_account *) aCallocA(sizeof(struct gm_account) * mysql_num_rows(lsql_res), 1);
while ((lsql_row = mysql_fetch_row(lsql_res))) {
gm_account[GM_num].account_id = atoi(lsql_row[0]);
gm_account[GM_num].level = atoi(lsql_row[1]);
@@ -7496,7 +7028,7 @@ int pc_read_gm_account(int fd)
GM_num++;
}
}
-
+
mysql_free_result(lsql_res);
#endif /* TXT_ONLY */
return GM_num;
@@ -7516,9 +7048,13 @@ int map_day_timer(int tid, unsigned int tick, int id, int data) { // by [yor]
strcpy(tmpstr, msg_txt(502)); // The day has arrived!
night_flag = 0; // 0=day, 1=night [Yor]
for(i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
- pl_sd->opt2 &= ~STATE_BLIND;
- clif_changeoption(&pl_sd->bl);
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth) {
+ if (battle_config.night_darkness_level > 0)
+ clif_refresh (pl_sd);
+ else {
+ pl_sd->opt2 &= ~STATE_BLIND;
+ clif_changeoption(&pl_sd->bl);
+ }
clif_wis_message(pl_sd->fd, wisp_server_name, tmpstr, strlen(tmpstr)+1);
}
}
@@ -7542,7 +7078,7 @@ int map_night_timer(int tid, unsigned int tick, int id, int data) { // by [yor]
strcpy(tmpstr, msg_txt(503)); // The night has fallen...
night_flag = 1; // 0=day, 1=night [Yor]
for(i = 0; i < fd_max; i++) {
- if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth && !map[pl_sd->bl.m].flag.indoors) {
+ if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && !map[pl_sd->bl.m].flag.indoors) {
if (battle_config.night_darkness_level > 0)
clif_specialeffect(&pl_sd->bl, 474 + battle_config.night_darkness_level, 0);
else {
@@ -7562,8 +7098,8 @@ int map_night_timer(int tid, unsigned int tick, int id, int data) { // by [yor]
void pc_setstand(struct map_session_data *sd){
nullpo_retv(sd);
- if(sd->sc_data && sd->sc_data[SC_TENSIONRELAX].timer!=-1)
- skill_status_change_end(&sd->bl,SC_TENSIONRELAX,-1);
+ if(sd->sc_count && sd->sc_data[SC_TENSIONRELAX].timer!=-1)
+ status_change_end(&sd->bl,SC_TENSIONRELAX,-1);
sd->state.dead_sit = 0;
}
@@ -7590,7 +7126,7 @@ int pc_readdb(void)
char line[1024],*p;
// •K—v??’l?‚Ý?‚Ý
-
+ memset(exp_table,0,sizeof(exp_table));
fp=fopen("db/exp.txt","r");
if(fp==NULL){
printf("can't read db/exp.txt\n");
@@ -7622,93 +7158,8 @@ int pc_readdb(void)
break;
}
fclose(fp);
- printf("read db/exp.txt done\n");
-
- // JOB•â³?’l‚P
- fp=fopen("db/job_db1.txt","r");
- if(fp==NULL){
- printf("can't read db/job_db1.txt\n");
- return 1;
- }
- i=0;
- while(fgets(line, sizeof(line)-1, fp)){
- char *split[50];
- if(line[0]=='/' && line[1]=='/')
- continue;
- for(j=0,p=line;j<21 && p;j++){
- split[j]=p;
- p=strchr(p,',');
- if(p) *p++=0;
- }
- if(j<21)
- continue;
- max_weight_base[i]=atoi(split[0]);
- hp_coefficient[i]=atoi(split[1]);
- hp_coefficient2[i]=atoi(split[2]);
- sp_coefficient[i]=atoi(split[3]);
- for(j=0;j<17;j++)
- aspd_base[i][j]=atoi(split[j+4]);
- i++;
-// -- moonsoul (below two lines added to accommodate high numbered new class ids)
- if(i==24)
- i=4001;
- if(i==MAX_PC_CLASS)
- break;
- }
- fclose(fp);
- printf("read db/job_db1.txt done\n");
-
- // JOBƒ{?ƒiƒX
- fp=fopen("db/job_db2.txt","r");
- if(fp==NULL){
- printf("can't read db/job_db2.txt\n");
- return 1;
- }
- i=0;
- while(fgets(line, sizeof(line)-1, fp)){
- if(line[0]=='/' && line[1]=='/')
- continue;
- for(j=0,p=line;j<MAX_LEVEL && p;j++){
- if(sscanf(p,"%d",&k)==0)
- break;
- job_bonus[0][i][j]=k;
- job_bonus[2][i][j]=k; //—{ŽqE‚̃{?ƒiƒX‚Í•ª‚©‚ç‚È‚¢‚Ì‚Å?
- p=strchr(p,',');
- if(p) p++;
- }
- i++;
-// -- moonsoul (below two lines added to accommodate high numbered new class ids)
- if(i==24)
- i=4001;
- if(i==MAX_PC_CLASS)
- break;
- }
- fclose(fp);
- printf("read db/job_db2.txt done\n");
-
- // JOBƒ{?ƒiƒX2 ?¶E—p
- fp=fopen("db/job_db2-2.txt","r");
- if(fp==NULL){
- printf("can't read db/job_db2-2.txt\n");
- return 1;
- }
- i=0;
- while(fgets(line, sizeof(line)-1, fp)){
- if(line[0]=='/' && line[1]=='/')
- continue;
- for(j=0,p=line;j<MAX_LEVEL && p;j++){
- if(sscanf(p,"%d",&k)==0)
- break;
- job_bonus[1][i][j]=k;
- p=strchr(p,',');
- if(p) p++;
- }
- i++;
- if(i==MAX_PC_CLASS)
- break;
- }
- fclose(fp);
- printf("read db/job_db2-2.txt done\n");
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/exp.txt");
+ ShowStatus(tmp_output);
// ƒXƒLƒ‹ƒcƒŠ?
memset(skill_tree,0,sizeof(skill_tree));
@@ -7720,36 +7171,41 @@ int pc_readdb(void)
while(fgets(line, sizeof(line)-1, fp)){
char *split[50];
+ int f=0, m=3;
if(line[0]=='/' && line[1]=='/')
continue;
- for(j=0,p=line;j<13 && p;j++){
+ for(j=0,p=line;j<14 && p;j++){
split[j]=p;
p=strchr(p,',');
if(p) *p++=0;
}
if(j<13)
continue;
- //i=atoi(split[0]);
+ if (j == 14) {
+ f=1; // MinJobLvl has been added
+ m++;
+ }
s_class = pc_calc_base_job(atoi(split[0]));
i = s_class.job;
u = s_class.upper;
- for(j=0;skill_tree[u][i][j].id;j++);
+ // check for bounds [celest]
+ if (i > 25 || u > 3)
+ continue;
+ for(j = 0; skill_tree[u][i][j].id && j < MAX_SKILL_TREE; j++);
+ if (j == MAX_SKILL_TREE)
+ continue;
skill_tree[u][i][j].id=atoi(split[1]);
skill_tree[u][i][j].max=atoi(split[2]);
-
- //not required - Celest
- //skill_tree[2][i][j].id=atoi(split[1]); //—{ŽqE‚Í—Ç‚­•ª‚©‚ç‚È‚¢‚̂Ŏb’è
- //skill_tree[2][i][j].max=atoi(split[2]); //—{ŽqE‚Í—Ç‚­•ª‚©‚ç‚È‚¢‚̂Ŏb’è
+ if (f) skill_tree[u][i][j].joblv=atoi(split[3]);
for(k=0;k<5;k++){
- skill_tree[u][i][j].need[k].id=atoi(split[k*2+3]);
- skill_tree[u][i][j].need[k].lv=atoi(split[k*2+4]);
- //skill_tree[2][i][j].need[k].id=atoi(split[k*2+3]); //—{ŽqE‚Í—Ç‚­•ª‚©‚ç‚È‚¢‚̂Ŏb’è
- //skill_tree[2][i][j].need[k].lv=atoi(split[k*2+4]); //—{ŽqE‚Í—Ç‚­•ª‚©‚ç‚È‚¢‚̂Ŏb’è
+ skill_tree[u][i][j].need[k].id=atoi(split[k*2+m]);
+ skill_tree[u][i][j].need[k].lv=atoi(split[k*2+m+1]);
}
}
fclose(fp);
- printf("read db/skill_tree.txt done\n");
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/skill_tree.txt");
+ ShowStatus(tmp_output);
// ?«C³ƒe?ƒuƒ‹
for(i=0;i<4;i++)
@@ -7795,135 +7251,52 @@ int pc_readdb(void)
}
}
fclose(fp);
- printf("read db/attr_fix.txt done\n");
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/attr_fix.txt");
+ ShowStatus(tmp_output);
- // ƒTƒCƒY•ⳃe?ƒuƒ‹
- for(i=0;i<3;i++)
- for(j=0;j<20;j++)
- atkmods[i][j]=100;
- fp=fopen("db/size_fix.txt","r");
- if(fp==NULL){
- printf("can't read db/size_fix.txt\n");
- return 1;
- }
- i=0;
- while(fgets(line, sizeof(line)-1, fp)){
- char *split[20];
- if(line[0]=='/' && line[1]=='/')
- continue;
- if(atoi(line)<=0)
- continue;
- memset(split,0,sizeof(split));
- for(j=0,p=line;j<20 && p;j++){
- split[j]=p;
- p=strchr(p,',');
- if(p) *p++=0;
+ // ƒXƒLƒ‹ƒcƒŠ?
+ memset(statp,0,sizeof(statp));
+ i=1;
+ j=45; // base points
+ fp=fopen("db/statpoint.txt","r");
+ if(fp == NULL){
+ sprintf(tmp_output,"Can't read '"CL_WHITE"%s"CL_RESET"'... Generating DB.\n","db/statpoint.txt");
+ //return 1;
+ } else {
+ while(fgets(line, sizeof(line)-1, fp)){
+ if(line[0]=='/' && line[1]=='/')
+ continue;
+ if ((j=atoi(line))<0)
+ j=0;
+ if (i >= MAX_LEVEL)
+ break;
+ statp[i]=j;
+ i++;
}
- for(j=0;j<20 && split[j];j++)
- atkmods[i][j]=atoi(split[j]);
- i++;
- }
- fclose(fp);
- printf("read db/size_fix.txt done\n");
-
- // ¸?ƒf?ƒ^ƒe?ƒuƒ‹
- for(i=0;i<5;i++){
- for(j=0;j<10;j++)
- percentrefinery[i][j]=100;
- refinebonus[i][0]=0;
- refinebonus[i][1]=0;
- refinebonus[i][2]=10;
- }
- fp=fopen("db/refine_db.txt","r");
- if(fp==NULL){
- printf("can't read db/refine_db.txt\n");
- return 1;
+ fclose(fp);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/statpoint.txt");
}
- i=0;
- while(fgets(line, sizeof(line)-1, fp)){
- char *split[16];
- if(line[0]=='/' && line[1]=='/')
- continue;
- if(atoi(line)<=0)
- continue;
- memset(split,0,sizeof(split));
- for(j=0,p=line;j<16 && p;j++){
- split[j]=p;
- p=strchr(p,',');
- if(p) *p++=0;
- }
- refinebonus[i][0]=atoi(split[0]); // ¸?ƒ{?ƒiƒX
- refinebonus[i][1]=atoi(split[1]); // ‰ß?¸?ƒ{?ƒiƒX
- refinebonus[i][2]=atoi(split[2]); // ˆÀ‘S¸?ŒÀŠE
- for(j=0;j<10 && split[j];j++)
- percentrefinery[i][j]=atoi(split[j+3]);
- i++;
+ // generate the remaining parts of the db if necessary
+ for (; i < MAX_LEVEL; i++) {
+ j += (i+15)/5;
+ statp[i] = j;
}
- fclose(fp); //Lupus. close this file!!!
- printf("read db/refine_db.txt done\n");
-
- return 0;
-}
-
-static int pc_calc_sigma(void)
-{
- int i,j,k;
+ ShowStatus(tmp_output);
- for(i=0;i<MAX_PC_CLASS;i++) {
- memset(hp_sigma_val[i],0,sizeof(hp_sigma_val[i]));
- for(k=0,j=2;j<=MAX_LEVEL;j++) {
- k += hp_coefficient[i]*j + 50;
- k -= k%100;
- hp_sigma_val[i][j-1] = k;
- }
- }
return 0;
}
-static void pc_statpointdb(void)
-{
- char * buf_stat;
- int i=0,j=0,k=0,l=0, end = 0;
-
- FILE *stp;
-
- stp=fopen("db/statpoint.txt","r");
-
- if(stp==NULL){
- printf("can't read db/statpoint.txt\n");
- return;
- }
-
- fseek(stp, 0, SEEK_END);
- end = ftell(stp);
- rewind(stp);
-
- buf_stat = (char *) malloc (end + 1);
- l = fread(buf_stat,1,end,stp);
- fclose(stp);
- printf("read db/statpoint.txt done (size=%d)\n",l);
-
- for(i=0;i<255;i++) {
- j=0;
- while (*(buf_stat+k)!='\n') {
- statp[i][j]=*(buf_stat+k);
- j++;k++;
- }
- statp[i][j+1]='\0';
- k++;
- }
-
- free(buf_stat);
-}
-
/*==========================================
* pc? ŒW‰Šú‰»
*------------------------------------------
*/
+void do_final_pc(void) {
+ if (gm_account)
+ aFree(gm_account);
+ return;
+}
int do_init_pc(void) {
pc_readdb();
- pc_statpointdb();
- pc_calc_sigma();
// gm_account_db = numdb_init();
@@ -7942,16 +7315,13 @@ int do_init_pc(void) {
pc_read_gm_account(0);
#endif /* not TXT_ONLY */
- // add night/day timer (by [yor])
- add_timer_func_list(map_day_timer, "map_day_timer"); // by [yor]
- add_timer_func_list(map_night_timer, "map_night_timer"); // by [yor]
- {
+ if (battle_config.day_duration > 0 && battle_config.night_duration > 0) {
int day_duration = battle_config.day_duration;
int night_duration = battle_config.night_duration;
- if (day_duration < 60000)
- day_duration = 60000;
- if (night_duration < 60000)
- night_duration = 60000;
+ // add night/day timer (by [yor])
+ add_timer_func_list(map_day_timer, "map_day_timer"); // by [yor]
+ add_timer_func_list(map_night_timer, "map_night_timer"); // by [yor]
+
if (battle_config.night_at_start == 0) {
night_flag = 0; // 0=day, 1=night [Yor]
day_timer_tid = add_timer_interval(gettick() + day_duration + night_duration, map_day_timer, 0, 0, day_duration + night_duration);
diff --git a/src/map/pc.h b/src/map/pc.h
index 372dd72f7..6aec36d38 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -7,6 +7,9 @@
#define OPTION_MASK 0xd7b8
#define CART_MASK 0x788
+#define STATE_BLIND 0x10
+
+#define MAX_SKILL_TREE 51
#define pc_setdead(sd) ((sd)->state.dead_sit = 1)
#define pc_setsit(sd) ((sd)->state.dead_sit = 2)
@@ -37,14 +40,19 @@ int pc_authfail(int);
int pc_isequip(struct map_session_data *sd,int n);
int pc_equippoint(struct map_session_data *sd,int n);
-int pc_breakweapon(struct map_session_data *sd); // weapon breaking [Valaris]
-int pc_breakarmor(struct map_session_data *sd); // armor breaking [Valaris]
+int pc_break_equip(struct map_session_data *, unsigned short);
+#define pc_breakweapon(sd) (pc_break_equip(sd, EQP_WEAPON))
+#define pc_breakarmor(sd) (pc_break_equip(sd, EQP_ARMOR))
+#define pc_breakshield(sd) (pc_break_equip(sd, EQP_SHIELD))
+#define pc_breakhelm(sd) (pc_break_equip(sd, EQP_HELM))
int pc_checkskill(struct map_session_data *sd,int skill_id);
int pc_checkallowskill(struct map_session_data *sd);
int pc_checkequip(struct map_session_data *sd,int pos);
+int pc_calc_skilltree(struct map_session_data *sd);
int pc_calc_skilltree_normalize_job(int c, struct map_session_data *sd);
+int pc_clean_skilltree(struct map_session_data *sd);
int pc_checkoverhp(struct map_session_data*);
int pc_checkoversp(struct map_session_data*);
@@ -57,6 +65,8 @@ int pc_setpos(struct map_session_data*,char*,int,int,int);
int pc_setsavepoint(struct map_session_data*,char*,int,int);
int pc_randomwarp(struct map_session_data *sd,int type);
int pc_memo(struct map_session_data *sd,int i);
+int pc_randomwalk(struct map_session_data*,int tick);
+int pc_remove_map(struct map_session_data *sd,int clrtype);
int pc_checkadditem(struct map_session_data*,int,int);
int pc_inventoryblank(struct map_session_data*);
@@ -78,13 +88,14 @@ int pc_dropitem(struct map_session_data*,int,int);
int pc_checkweighticon(struct map_session_data *sd);
-int pc_calcstatus(struct map_session_data*,int);
-int pc_calcspeed(struct map_session_data*); // [Celest]
int pc_bonus(struct map_session_data*,int,int);
int pc_bonus2(struct map_session_data *sd,int,int,int);
int pc_bonus3(struct map_session_data *sd,int,int,int,int);
+int pc_bonus4(struct map_session_data *sd,int,int,int,int,int);
int pc_skill(struct map_session_data*,int,int,int);
+int pc_blockskill_start (struct map_session_data*,int,int); // [celest]
+
int pc_insert_card(struct map_session_data *sd,int idx_card,int idx_equip);
int pc_item_identify(struct map_session_data *sd,int idx);
@@ -117,7 +128,7 @@ int pc_resetlvl(struct map_session_data*,int type);
int pc_resetstate(struct map_session_data*);
int pc_resetskill(struct map_session_data*);
int pc_equipitem(struct map_session_data*,int,int);
-int pc_unequipitem(struct map_session_data*,int,int,int);
+int pc_unequipitem(struct map_session_data*,int,int);
int pc_checkitem(struct map_session_data*);
int pc_useitem(struct map_session_data*,int);
@@ -145,7 +156,6 @@ int pc_readaccountreg(struct map_session_data*,char*);
int pc_setaccountreg(struct map_session_data*,char*,int);
int pc_readaccountreg2(struct map_session_data*,char*);
int pc_setaccountreg2(struct map_session_data*,char*,int);
-int pc_percentrefinery(struct map_session_data *sd,struct item *item);
int pc_addeventtimer(struct map_session_data *sd,int tick,const char *name);
int pc_deleventtimer(struct map_session_data *sd,const char *name);
@@ -158,10 +168,16 @@ int pc_calc_pvprank_timer(int tid,unsigned int tick,int id,int data);
int pc_ismarried(struct map_session_data *sd);
int pc_marriage(struct map_session_data *sd,struct map_session_data *dstsd);
int pc_divorce(struct map_session_data *sd);
+int pc_adoption(struct map_session_data *sd,struct map_session_data *dstsd,struct map_session_data *jasd);
struct map_session_data *pc_get_partner(struct map_session_data *sd);
+struct map_session_data *pc_get_father(struct map_session_data *sd);
+struct map_session_data *pc_get_mother(struct map_session_data *sd);
+struct map_session_data *pc_get_child(struct map_session_data *sd);
+
int pc_set_gm_level(int account_id, int level);
void pc_setstand(struct map_session_data *sd);
-
+int pc_break_equip(struct map_session_data *sd, unsigned short where);
+int pc_candrop(struct map_session_data *sd,int item_id);
struct pc_base_job{
int job; //E‹ÆA‚½‚¾‚µ“]¶E‚â—{ŽqE‚Ìꇂ͌³‚ÌE‹Æ‚ð•Ô‚·(”pƒvƒŠ¨ƒvƒŠ)
@@ -174,12 +190,15 @@ int pc_calc_base_job2(int b_class); // Celest
int pc_calc_upper(int b_class);
struct skill_tree_entry {
- int id;
- int max;
+ short id;
+ unsigned char max;
+ unsigned char joblv;
struct {
- short id,lv;
- } need[6];
-} skill_tree[3][MAX_PC_CLASS][100]; // Celest
+ short id;
+ unsigned char lv;
+ } need[5];
+}; // Celest
+extern struct skill_tree_entry skill_tree[3][25][MAX_SKILL_TREE];
int pc_read_gm_account(int fd);
int pc_setinvincibletimer(struct map_session_data *sd,int);
@@ -187,13 +206,17 @@ int pc_delinvincibletimer(struct map_session_data *sd);
int pc_addspiritball(struct map_session_data *sd,int,int);
int pc_delspiritball(struct map_session_data *sd,int,int);
+int pc_eventtimer(int tid,unsigned int tick,int id,int data); // for npc_dequeue
+
+int pc_readdb(void);
int do_init_pc(void);
+void do_final_pc(void);
enum {ADDITEM_EXIST,ADDITEM_NEW,ADDITEM_OVERAMOUNT};
// timer for night.day
-int day_timer_tid;
-int night_timer_tid;
+extern int day_timer_tid;
+extern int night_timer_tid;
int map_day_timer(int,unsigned int,int,int); // by [yor]
int map_night_timer(int,unsigned int,int,int); // by [yor]
diff --git a/src/map/pet.c b/src/map/pet.c
index 6026b1ebf..6f4713d75 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -9,6 +9,7 @@
#include "nullpo.h"
#include "malloc.h"
#include "pc.h"
+#include "status.h"
#include "map.h"
#include "intif.h"
#include "clif.h"
@@ -20,6 +21,7 @@
#include "npc.h"
#include "script.h"
#include "skill.h"
+#include "showmsg.h"
#ifdef MEMWATCH
#include "memwatch.h"
@@ -48,6 +50,8 @@ static int calc_next_walk_step(struct pet_data *pd)
{
nullpo_retr(0, pd);
+ Assert((pd->msd == 0) || (pd->msd->pd == pd));
+
if(pd->walkpath.path_pos>=pd->walkpath.path_len)
return -1;
if(pd->walkpath.path[pd->walkpath.path_pos]&1)
@@ -59,6 +63,8 @@ static int pet_performance_val(struct map_session_data *sd)
{
nullpo_retr(0, sd);
+ Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
+
if(sd->pet.intimate > 900)
return (sd->petDB->s_perfor > 0)? 4:3;
else if(sd->pet.intimate > 750)
@@ -71,6 +77,8 @@ int pet_hungry_val(struct map_session_data *sd)
{
nullpo_retr(0, sd);
+ Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
+
if(sd->pet.hungry > 90)
return 4;
else if(sd->pet.hungry > 75)
@@ -89,6 +97,8 @@ static int pet_can_reach(struct pet_data *pd,int x,int y)
nullpo_retr(0, pd);
+ Assert((pd->msd == 0) || (pd->msd->pd == pd));
+
if( pd->bl.x==x && pd->bl.y==y ) // “¯‚¶ƒ}ƒX
return 1;
@@ -106,6 +116,8 @@ static int pet_calc_pos(struct pet_data *pd,int tx,int ty,int dir)
nullpo_retr(0, pd);
+ Assert((pd->msd == 0) || (pd->msd->pd == pd));
+
pd->to_x = tx;
pd->to_y = ty;
@@ -161,23 +173,27 @@ static int pet_attack(struct pet_data *pd,unsigned int tick,int data)
nullpo_retr(0, pd);
+ Assert((pd->msd == 0) || (pd->msd->pd == pd));
+
pd->state.state=MS_IDLE;
md=(struct mob_data *)map_id2bl(pd->target_id);
if(md == NULL || md->bl.type != BL_MOB || pd->bl.m != md->bl.m || md->bl.prev == NULL ||
- distance(pd->bl.x,pd->bl.y,md->bl.x,md->bl.y) > 13) {
+ distance(pd->bl.x,pd->bl.y,md->bl.x,md->bl.y) > 13 ||
+ (!agit_flag && md->class_ >= 1285 && md->class_ <= 1288)) // Cannot attack Guardians outside of WoE
+ {
pd->target_id=0;
return 0;
}
- mode=mob_db[pd->class].mode;
- race=mob_db[pd->class].race;
- if(mob_db[pd->class].mexp <= 0 && !(mode&0x20) && (md->option & 0x06 && race != 4 && race != 6) ) {
+ mode=mob_db[pd->class_].mode;
+ race=mob_db[pd->class_].race;
+ if(mob_db[pd->class_].mexp <= 0 && !(mode&0x20) && (md->option & 0x06 && race != 4 && race != 6) ) {
pd->target_id=0;
return 0;
}
- range = mob_db[pd->class].range + 1;
+ range = mob_db[pd->class_].range + 1;
if(distance(pd->bl.x,pd->bl.y,md->bl.x,md->bl.y) > range)
return 0;
if(battle_config.monster_attack_direction_change)
@@ -187,7 +203,7 @@ static int pet_attack(struct pet_data *pd,unsigned int tick,int data)
pd->target_lv = battle_weapon_attack(&pd->bl,&md->bl,tick,0);
- pd->attackabletime = tick + battle_get_adelay(&pd->bl);
+ pd->attackabletime = tick + status_get_adelay(&pd->bl);
pd->timer=add_timer(pd->attackabletime,pet_timer,pd->bl.id,0);
pd->state.state=MS_ATTACK;
@@ -202,11 +218,13 @@ static int pet_attack(struct pet_data *pd,unsigned int tick,int data)
static int pet_walk(struct pet_data *pd,unsigned int tick,int data)
{
int moveblock;
- int i,ctype;
+ int i;
int x,y,dx,dy;
nullpo_retr(0, pd);
+ Assert((pd->msd == 0) || (pd->msd->pd == pd));
+
pd->state.state=MS_IDLE;
if(pd->walkpath.path_pos >= pd->walkpath.path_len || pd->walkpath.path_pos != data)
return 0;
@@ -234,8 +252,7 @@ static int pet_walk(struct pet_data *pd,unsigned int tick,int data)
dx = dirx[pd->dir];
dy = diry[pd->dir];
- ctype = map_getcell(pd->bl.m,x+dx,y+dy);
- if(ctype == 1 || ctype == 5) {
+ if(map_getcell(pd->bl.m,x+dx,y+dy,CELL_CHKNOPASS)){
pet_walktoxy_sub(pd);
return 0;
}
@@ -273,6 +290,8 @@ int pet_stopattack(struct pet_data *pd)
{
nullpo_retr(0, pd);
+ Assert((pd->msd == 0) || (pd->msd->pd == pd));
+
pd->target_id=0;
if(pd->state.state == MS_ATTACK)
pet_changestate(pd,MS_IDLE,0);
@@ -290,15 +309,17 @@ int pet_target_check(struct map_session_data *sd,struct block_list *bl,int type)
pd = sd->pd;
- if(bl && pd && bl->type == BL_MOB && sd->pet.intimate > 900 && sd->pet.hungry > 0 && pd->class != battle_get_class(bl)
+ Assert((pd->msd == 0) || (pd->msd->pd == pd));
+
+ if(bl && pd && bl->type == BL_MOB && sd->pet.intimate > 900 && sd->pet.hungry > 0 && pd->class_ != status_get_class(bl)
&& pd->state.state != MS_DELAY) {
- mode=mob_db[pd->class].mode;
- race=mob_db[pd->class].race;
+ mode=mob_db[pd->class_].mode;
+ race=mob_db[pd->class_].race;
md=(struct mob_data *)bl;
if(md->bl.type != BL_MOB || pd->bl.m != md->bl.m || md->bl.prev == NULL ||
distance(pd->bl.x,pd->bl.y,md->bl.x,md->bl.y) > 13)
return 0;
- if(mob_db[pd->class].mexp <= 0 && !(mode&0x20) && (md->option & 0x06 && race!=4 && race!=6) )
+ if(mob_db[pd->class_].mexp <= 0 && !(mode&0x20) && (md->option & 0x06 && race!=4 && race!=6) )
return 0;
if(!type) {
rate = sd->petDB->attack_rate;
@@ -331,6 +352,8 @@ int pet_changestate(struct pet_data *pd,int state,int type)
nullpo_retr(0, pd);
+ Assert((pd->msd == 0) || (pd->msd->pd == pd));
+
if(pd->timer != -1)
delete_timer(pd->timer,pet_timer);
pd->timer=-1;
@@ -368,6 +391,8 @@ static int pet_timer(int tid,unsigned int tick,int id,int data)
if(pd == NULL || pd->bl.type != BL_PET)
return 1;
+ Assert((pd->msd == 0) || (pd->msd->pd == pd));
+
if(pd->timer != tid){
if(battle_config.error_log)
printf("pet_timer %d != %d\n",pd->timer,tid);
@@ -403,6 +428,8 @@ static int pet_walktoxy_sub(struct pet_data *pd)
nullpo_retr(0, pd);
+ Assert((pd->msd == 0) || (pd->msd->pd == pd));
+
if(path_search(&wpd,pd->bl.m,pd->bl.x,pd->bl.y,pd->to_x,pd->to_y,0))
return 1;
memcpy(&pd->walkpath,&wpd,sizeof(wpd));
@@ -422,6 +449,8 @@ int pet_walktoxy(struct pet_data *pd,int x,int y)
nullpo_retr(0, pd);
+ Assert((pd->msd == 0) || (pd->msd->pd == pd));
+
if(pd->state.state == MS_WALK && path_search(&wpd,pd->bl.m,pd->bl.x,pd->bl.y,x,y,0))
return 1;
@@ -441,6 +470,8 @@ int pet_stop_walking(struct pet_data *pd,int type)
{
nullpo_retr(0, pd);
+ Assert((pd->msd == 0) || (pd->msd->pd == pd));
+
if(pd->state.state == MS_WALK || pd->state.state == MS_IDLE) {
pd->walkpath.path_len=0;
pd->to_x=pd->bl.x;
@@ -461,10 +492,13 @@ static int pet_hungry(int tid,unsigned int tick,int id,int data)
struct map_session_data *sd;
int interval,t;
+
sd=map_id2sd(id);
if(sd==NULL)
return 1;
+ Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
+
if(sd->pet_hungry_timer != tid){
if(battle_config.error_log)
printf("pet_hungry_timer %d != %d\n",sd->pet_hungry_timer,tid);
@@ -485,9 +519,9 @@ static int pet_hungry(int tid,unsigned int tick,int id,int data)
sd->pet.intimate = 0;
if(battle_config.pet_status_support && t > 0) {
if(sd->bl.prev != NULL)
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
else
- pc_calcstatus(sd,2);
+ status_calc_pc(sd,2);
}
}
clif_send_petdata(sd,1,sd->pet.intimate);
@@ -510,11 +544,11 @@ int search_petDB_index(int key,int type)
int i;
for(i=0;i<MAX_PET_DB;i++) {
- if(pet_db[i].class <= 0)
+ if(pet_db[i].class_ <= 0)
continue;
switch(type) {
case PET_CLASS:
- if(pet_db[i].class == key)
+ if(pet_db[i].class_ == key)
return i;
break;
case PET_CATCH:
@@ -556,26 +590,29 @@ int pet_remove_map(struct map_session_data *sd)
{
nullpo_retr(0, sd);
+ Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
+
if(sd->status.pet_id && sd->pd) {
struct pet_data *pd=sd->pd; // [Valaris]
if(pd->skillbonustimer!=-1) pd->skillbonustimer=-1;
- if(pd->skillbonusduration!=-1) pd->skillbonusduration=-1;
- if(pd->skilltype !=-1) pd->skilltype=-1;
- if(pd->skillval !=-1) pd->skillval=-1;
+ pd->skilltype=0;
+ pd->skillval=0;
if(pd->skilltimer!=-1) pd->skilltimer=-1;
- if(pd->skillduration!=-1) pd->skillduration=-1;
- if(pd->skillbonustype!=-1) pd->skillbonustype=-1;
- if(pd->skillbonusval!=-1) pd->skillbonusval=-1;
- if(sd->perfect_hiding==1) sd->perfect_hiding=0; // end additions
+ pd->state.skillbonus=-1;
+ pd->skillduration=0;
+ pd->skillbonustype=0;
+ pd->skillbonusval=0;
+ if(sd->perfect_hiding==1) sd->perfect_hiding=0; // end additions
pet_changestate(sd->pd,MS_IDLE,0);
if(sd->pet_hungry_timer != -1)
pet_hungry_timer_delete(sd);
clif_clearchar_area(&sd->pd->bl,0);
map_delblock(&sd->pd->bl);
+ if (sd->pd->lootitem)
+ aFree(sd->pd->lootitem);
map_deliddb(&sd->pd->bl);
- map_freeblock(sd->pd);
}
return 0;
}
@@ -598,6 +635,8 @@ int pet_performance(struct map_session_data *sd)
nullpo_retr(0, sd);
nullpo_retr(0, pd=sd->pd);
+ Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
+
pet_stop_walking(pd,2000<<8);
clif_pet_performance(&pd->bl,rand()%pet_performance_val(sd) + 1);
// ƒ‹[ƒg‚µ‚½Item‚𗎂Ƃ³‚¹‚é
@@ -613,8 +652,11 @@ int pet_return_egg(struct map_session_data *sd)
nullpo_retr(0, sd);
+ Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
+
if(sd->status.pet_id && sd->pd) {
- struct pet_data *pd=sd->pd;
+ // ƒ‹[ƒg‚µ‚½Item‚𗎂Ƃ³‚¹‚é
+ pet_lootitem_drop(sd->pd,sd);
pet_remove_map(sd);
sd->status.pet_id = 0;
sd->pd = NULL;
@@ -634,12 +676,10 @@ int pet_return_egg(struct map_session_data *sd)
}
if(battle_config.pet_status_support && sd->pet.intimate > 0) {
if(sd->bl.prev != NULL)
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
else
- pc_calcstatus(sd,2);
+ status_calc_pc(sd,2);
}
- // ƒ‹[ƒg‚µ‚½Item‚𗎂Ƃ³‚¹‚é
- pet_lootitem_drop(pd,sd);
intif_save_petdata(sd->status.account_id,&sd->pet);
pc_makesavestatus(sd);
@@ -659,13 +699,15 @@ int pet_data_init(struct map_session_data *sd)
nullpo_retr(1, sd);
+ Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
+
if(sd->status.account_id != sd->pet.account_id || sd->status.char_id != sd->pet.char_id ||
sd->status.pet_id != sd->pet.pet_id) {
sd->status.pet_id = 0;
return 1;
}
- i = search_petDB_index(sd->pet.class,PET_CLASS);
+ i = search_petDB_index(sd->pet.class_,PET_CLASS);
if(i < 0) {
sd->status.pet_id = 0;
return 1;
@@ -682,7 +724,7 @@ int pet_data_init(struct map_session_data *sd)
pd->bl.y = pd->to_y;
pd->bl.id = npc_get_new_npc_id();
memcpy(pd->name,sd->pet.name,24);
- pd->class = sd->pet.class;
+ pd->class_ = sd->pet.class_;
pd->equip = sd->pet.equip;
pd->dir = sd->dir;
pd->speed = sd->petDB->speed;
@@ -696,9 +738,13 @@ int pet_data_init(struct map_session_data *sd)
pd->move_fail_count = 0;
pd->next_walktime = pd->attackabletime = pd->last_thinktime = gettick();
pd->msd = sd;
-
+
map_addiddb(&pd->bl);
+ // initialise
+ pd->state.skillbonus = -1;
+ run_script(pet_db[i].script,0,sd->bl.id,0);
+
if(sd->pet_hungry_timer != -1)
pet_hungry_timer_delete(sd);
if(battle_config.pet_hungry_delay_rate != 100)
@@ -719,6 +765,8 @@ int pet_birth_process(struct map_session_data *sd)
{
nullpo_retr(1, sd);
+ Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
+
if(sd->status.pet_id && sd->pet.incuvate == 1) {
sd->status.pet_id = 0;
return 1;
@@ -747,6 +795,8 @@ int pet_birth_process(struct map_session_data *sd)
clif_pet_equip(sd->pd,sd->pet.equip);
clif_send_petstatus(sd);
+ Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
+
return 0;
}
@@ -766,7 +816,7 @@ int pet_recv_petdata(int account_id,struct s_pet *p,int flag)
pet_birth_process(sd);
else {
pet_data_init(sd);
- if(sd->bl.prev != NULL) {
+ if(sd->pd && sd->bl.prev != NULL) {
map_addblock(&sd->pd->bl);
clif_spawnpet(sd->pd);
clif_send_petdata(sd,0,0);
@@ -777,9 +827,9 @@ int pet_recv_petdata(int account_id,struct s_pet *p,int flag)
}
if(battle_config.pet_status_support && sd->pet.intimate > 0) {
if(sd->bl.prev != NULL)
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
else
- pc_calcstatus(sd,2);
+ status_calc_pc(sd,2);
}
return 0;
@@ -823,27 +873,28 @@ int pet_catch_process2(struct map_session_data *sd,int target_id)
return 1;
}
- i = search_petDB_index(md->class,PET_CLASS);
- if(md == NULL || md->bl.type != BL_MOB || md->bl.prev == NULL || i < 0 || sd->catch_target_class != md->class) {
+ i = search_petDB_index(md->class_,PET_CLASS);
+ if(md == NULL || md->bl.type != BL_MOB || md->bl.prev == NULL || i < 0 || sd->catch_target_class != md->class_) {
clif_pet_rulet(sd,0);
return 1;
}
//target_id‚É‚æ‚é“G¨—‘”»’è
// if(battle_config.etc_log)
-// printf("mob_id = %d, mob_class = %d\n",md->bl.id,md->class);
+// printf("mob_id = %d, mob_class = %d\n",md->bl.id,md->class_);
//¬Œ÷‚Ìê‡
- pet_catch_rate = (pet_db[i].capture + (sd->status.base_level - mob_db[md->class].lv)*30 + sd->paramc[5]*20)*(200 - md->hp*100/mob_db[md->class].max_hp)/100;
+ pet_catch_rate = (pet_db[i].capture + (sd->status.base_level - mob_db[md->class_].lv)*30 + sd->paramc[5]*20)*(200 - md->hp*100/mob_db[md->class_].max_hp)/100;
if(pet_catch_rate < 1) pet_catch_rate = 1;
if(battle_config.pet_catch_rate != 100)
pet_catch_rate = (pet_catch_rate*battle_config.pet_catch_rate)/100;
if(rand()%10000 < pet_catch_rate) {
- mob_catch_delete(md,0);
+ mob_remove_map(md,0);
+ mob_setdelayspawn(md->bl.id);
clif_pet_rulet(sd,1);
// if(battle_config.etc_log)
// printf("rulet success %d\n",target_id);
- intif_create_pet(sd->status.account_id,sd->status.char_id,pet_db[i].class,mob_db[pet_db[i].class].lv,
+ intif_create_pet(sd->status.account_id,sd->status.char_id,pet_db[i].class_,mob_db[pet_db[i].class_].lv,
pet_db[i].EggID,0,pet_db[i].intimate,100,0,1,pet_db[i].jname);
}
else
@@ -869,7 +920,7 @@ int pet_get_egg(int account_id,int pet_id,int flag)
tmp_item.nameid = pet_db[i].EggID;
tmp_item.identify = 1;
tmp_item.card[0] = 0xff00;
- *((long *)(&tmp_item.card[1])) = pet_id;
+ tmp_item.card[1] = pet_id;
tmp_item.card[3] = sd->pet.rename_flag;
if((ret = pc_additem(sd,&tmp_item,1))) {
clif_additem(sd,0,0,ret);
@@ -913,7 +964,7 @@ int pet_change_name(struct map_session_data *sd,char *name)
nullpo_retr(1, sd);
- if(sd->pet.rename_flag == 1 && battle_config.pet_rename == 0)
+ if((sd->pd == NULL) || (sd->pet.rename_flag == 1 && battle_config.pet_rename == 0))
return 1;
for(i=0;i<24 && name[i];i++){
@@ -951,7 +1002,7 @@ int pet_equipitem(struct map_session_data *sd,int index)
else {
pc_delitem(sd,index,1,0);
sd->pet.equip = sd->pd->equip = nameid;
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
clif_pet_equip(sd->pd,nameid);
}
@@ -972,7 +1023,7 @@ int pet_unequipitem(struct map_session_data *sd)
nameid = sd->pet.equip;
sd->pet.equip = sd->pd->equip = 0;
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
clif_pet_equip(sd->pd,0);
memset(&tmp_item,0,sizeof(tmp_item));
tmp_item.nameid = nameid;
@@ -991,6 +1042,8 @@ int pet_food(struct map_session_data *sd)
nullpo_retr(1, sd);
+ Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
+
if(sd->petDB == NULL)
return 1;
i=pc_search_inventory(sd,sd->petDB->FoodID);
@@ -1023,9 +1076,9 @@ int pet_food(struct map_session_data *sd)
sd->pet.intimate = 0;
if(battle_config.pet_status_support && t > 0) {
if(sd->bl.prev != NULL)
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
else
- pc_calcstatus(sd,2);
+ status_calc_pc(sd,2);
}
}
else if(sd->pet.intimate > 1000)
@@ -1048,7 +1101,9 @@ static int pet_randomwalk(struct pet_data *pd,int tick)
nullpo_retr(0, pd);
- speed = battle_get_speed(&pd->bl);
+ Assert((pd->msd == 0) || (pd->msd->pd == pd));
+
+ speed = status_get_speed(&pd->bl);
if(DIFF_TICK(pd->next_walktime,tick) < 0){
int i,x,y,c,d=12-pd->move_fail_count;
@@ -1057,7 +1112,7 @@ static int pet_randomwalk(struct pet_data *pd,int tick)
int r=rand();
x=pd->bl.x+r%(d*2+1)-d;
y=pd->bl.y+r/(d*2+1)%(d*2+1)-d;
- if((c=map_getcell(pd->bl.m,x,y))!=1 && c!=5 && pet_walktoxy(pd,x,y)==0){
+ if((map_getcell(pd->bl.m,x,y,CELL_CHKPASS))&&( pet_walktoxy(pd,x,y)==0)){
pd->move_fail_count=0;
break;
}
@@ -1065,7 +1120,7 @@ static int pet_randomwalk(struct pet_data *pd,int tick)
pd->move_fail_count++;
if(pd->move_fail_count>1000){
if(battle_config.error_log)
- printf("PET cant move. hold position %d, class = %d\n",pd->bl.id,pd->class);
+ printf("PET cant move. hold position %d, class = %d\n",pd->bl.id,pd->class_);
pd->move_fail_count=0;
pet_changestate(pd,MS_DELAY,60000);
return 0;
@@ -1105,6 +1160,8 @@ static int pet_ai_sub_hard(struct pet_data *pd,unsigned int tick)
sd = pd->msd;
+ Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
+
if(pd->bl.prev == NULL || sd == NULL || sd->bl.prev == NULL)
return 0;
@@ -1136,22 +1193,22 @@ static int pet_ai_sub_hard(struct pet_data *pd,unsigned int tick)
pet_randomwalk(pd,tick);
}
else if(pd->target_id - MAX_FLOORITEM > 0) {
- mode=mob_db[pd->class].mode;
- race=mob_db[pd->class].race;
+ mode=mob_db[pd->class_].mode;
+ race=mob_db[pd->class_].race;
md=(struct mob_data *)map_id2bl(pd->target_id);
if(md == NULL || md->bl.type != BL_MOB || pd->bl.m != md->bl.m || md->bl.prev == NULL ||
distance(pd->bl.x,pd->bl.y,md->bl.x,md->bl.y) > 13)
pet_unlocktarget(pd);
- else if(mob_db[pd->class].mexp <= 0 && !(mode&0x20) && (md->option & 0x06 && race!=4 && race!=6) )
+ else if(mob_db[pd->class_].mexp <= 0 && !(mode&0x20) && (md->option & 0x06 && race!=4 && race!=6) )
pet_unlocktarget(pd);
- else if(!battle_check_range(&pd->bl,&md->bl,mob_db[pd->class].range)){
+ else if(!battle_check_range(&pd->bl,&md->bl,mob_db[pd->class_].range)){
if(pd->timer != -1 && pd->state.state == MS_WALK && distance(pd->to_x,pd->to_y,md->bl.x,md->bl.y) < 2)
return 0;
if( !pet_can_reach(pd,md->bl.x,md->bl.y))
pet_unlocktarget(pd);
else {
i=0;
- pd->speed = battle_get_speed(&pd->bl);
+ pd->speed = status_get_speed(&pd->bl);
do {
if(i==0) { // ʼn‚ÍAEGIS‚Æ“¯‚¶•û–@‚ÅŒŸõ
dx=md->bl.x - pd->bl.x;
@@ -1235,14 +1292,14 @@ static int pet_ai_sub_hard(struct pet_data *pd,unsigned int tick)
else {
if(dist <= 3 || (pd->timer != -1 && pd->state.state == MS_WALK && distance(pd->to_x,pd->to_y,sd->bl.x,sd->bl.y) < 3) )
return 0;
- pd->speed = battle_get_speed(&pd->bl);
+ pd->speed = status_get_speed(&pd->bl);
pet_calc_pos(pd,sd->bl.x,sd->bl.y,sd->dir);
if(pet_walktoxy(pd,pd->to_x,pd->to_y))
pet_randomwalk(pd,tick);
}
}
else {
- pd->speed = battle_get_speed(&pd->bl);
+ pd->speed = status_get_speed(&pd->bl);
if(pd->state.state == MS_ATTACK)
pet_stopattack(pd);
pet_randomwalk(pd,tick);
@@ -1326,13 +1383,12 @@ int pet_lootitem_drop(struct pet_data *pd,struct map_session_data *sd)
clif_additem(sd,0,0,flag);
map_addflooritem(&ditem->item_data,ditem->item_data.amount,ditem->m,ditem->x,ditem->y,ditem->first_sd,ditem->second_sd,ditem->third_sd,0);
}
- free(ditem);
+ aFree(ditem);
}
else
add_timer(gettick()+540+i,pet_delay_item_drop2,(int)ditem,0);
}
- pd->lootitem=NULL;
- pd->lootitem=(struct item *)aCalloc(PETLOOT_SIZE,sizeof(struct item));
+ memset(pd->lootitem,0,LOOTITEM_SIZE * sizeof(struct item));
pd->lootitem_count = 0;
pd->lootitem_weight = 0;
pd->lootitem_timer = gettick()+10000; // 10*1000ms‚ÌŠÔE‚í‚È‚¢
@@ -1349,7 +1405,7 @@ int pet_delay_item_drop2(int tid,unsigned int tick,int id,int data)
map_addflooritem(&ditem->item_data,ditem->item_data.amount,ditem->m,ditem->x,ditem->y,ditem->first_sd,ditem->second_sd,ditem->third_sd,0);
- free(ditem);
+ aFree(ditem);
return 0;
}
@@ -1357,29 +1413,13 @@ int pet_delay_item_drop2(int tid,unsigned int tick,int id,int data)
* pet bonus giving skills [Valaris]
*------------------------------------------
*/
-
-int pet_skill_bonus(struct map_session_data *sd,struct pet_data *pd,int type,int val,int duration,int timer,int data)
-{
- if(pd==NULL || sd==NULL)
- return 1;
-
- pd->skillbonustype=type;
- pd->skillbonusval=val;
- pd->skillduration=duration;
- pd->skilltimer=timer;
-
- pd->skillbonustimer=add_timer(gettick()+pd->skilltimer*1000,pet_skill_bonus_timer,sd->bl.id,0);
-
- return 0;
-
-}
-
int pet_skill_bonus_timer(int tid,unsigned int tick,int id,int data)
{
- struct map_session_data *sd=(struct map_session_data*)map_id2bl(id);
+ struct map_session_data *sd=map_id2sd(id);
struct pet_data *pd;
+ int timer = 0;
- if(sd==NULL || sd->bl.type!=BL_PC)
+ if(sd==NULL)
return 1;
pd=sd->pd;
@@ -1390,38 +1430,26 @@ int pet_skill_bonus_timer(int tid,unsigned int tick,int id,int data)
if(pd->skillbonustimer != tid)
return 0;
- pd->skillbonustimer=-1;
-
- pc_bonus(sd,pd->skillbonustype,pd->skillbonusval);
- if(pd->skillbonustype < 56) clif_updatestatus(sd,pd->skillbonustype);
- pd->skillbonusduration=add_timer(gettick()+pd->skillduration*1000,pet_skill_bonus_duration,sd->bl.id,0);
-
- return 0;
-}
-
-int pet_skill_bonus_duration(int tid,unsigned int tick,int id,int data)
-{
- struct map_session_data *sd=(struct map_session_data*)map_id2bl(id);
- struct pet_data *pd;
-
- if(sd==NULL || sd->bl.type!=BL_PC)
- return 1;
-
- pd=sd->pd;
-
- if(pd==NULL || pd->bl.type!=BL_PET)
- return 1;
-
- if(pd->skillbonusduration != tid)
- return 0;
-
- pd->skillbonusduration=-1;
+ // determine the time for the next timer
+ if (pd->state.skillbonus == 0) {
+ // pet bonuses are not active at the moment, so,
+ pd->state.skillbonus = 1;
+ timer = pd->skillduration; // the duration for pet bonuses to be in effect
+ } else if (pd->state.skillbonus == 1) {
+ // pet bonuses are already active, so,
+ pd->state.skillbonus = 0;
+ timer = pd->skilltimer; // the duration which pet bonuses will be reactivated again
+ }
- pc_bonus(sd,pd->skillbonustype,-pd->skillbonusval);
- if(pd->skillbonustype < 56) clif_updatestatus(sd,pd->skillbonustype);
+ if (pd->state.skillbonus == 1 && sd->petDB)
+ run_script(sd->petDB->script,0,sd->bl.id,0);
- pet_skill_bonus(sd,pd,pd->skillbonustype,pd->skillbonusval,pd->skillduration,pd->skilltimer,0);
+ // add/remove our bonuses, which will be handled by sd->petbonus[]
+ status_calc_pc(sd, 0);
+ // wait for the next timer
+ if (timer) pd->skillbonustimer=add_timer(gettick()+timer,pet_skill_bonus_timer,sd->bl.id,0);
+
return 0;
}
@@ -1442,7 +1470,7 @@ int pet_recovery_timer(int tid,unsigned int tick,int id,int data)
return 0;
if(sd->sc_data[pd->skilltype].timer != -1)
- skill_status_change_end(&sd->bl,pd->skilltype,-1);
+ status_change_end(&sd->bl,pd->skilltype,-1);
pd->skillbonustimer=add_timer(gettick()+pd->skilltimer*1000,pet_recovery_timer,sd->bl.id,0);
@@ -1493,7 +1521,7 @@ int pet_mag_timer(int tid,unsigned int tick,int id,int data)
if(sd->status.hp < sd->status.max_hp * pd->skilltype/100 && sd->status.sp < sd->status.max_sp * pd->skillduration/100) {
clif_skill_nodamage(&pd->bl,&sd->bl,PR_MAGNIFICAT,pd->skillval,1);
- skill_status_change_start(&sd->bl,SkillStatusChangeTable[PR_MAGNIFICAT],pd->skillval,0,0,0,skill_get_time(PR_MAGNIFICAT,pd->skillval),0 );
+ status_change_start(&sd->bl,SkillStatusChangeTable[PR_MAGNIFICAT],pd->skillval,0,0,0,skill_get_time(PR_MAGNIFICAT,pd->skillval),0 );
}
pd->skillbonustimer=add_timer(gettick()+pd->skilltimer*1000,pet_mag_timer,sd->bl.id,0);
@@ -1527,19 +1555,22 @@ int pet_skillattack_timer(int tid,unsigned int tick,int id,int data)
}
if(md && rand()%100 < sd->pet.intimate*pd->skilltimer/100 ) {
- if(pd->skilltype==6 || pd->skilltype==176) {
+ switch(pd->skilltype)
+ {
+ case SM_PROVOKE:
+ //case NPC_POISON: poison is not handled there
skill_castend_nodamage_id(&pd->bl,&md->bl,pd->skilltype,pd->skillval,tick,0);
- }
-
- else if(pd->skilltype==110){
+ break;
+ case BS_HAMMERFALL:
skill_castend_pos2(&pd->bl,md->bl.x,md->bl.y,pd->skilltype,pd->skillval,tick,0);
- }
-
- else if(pd->skilltype==91) {
+ break;
+ case WZ_HEAVENDRIVE:
skill_castend_pos2(&pd->bl,md->bl.x,md->bl.y,pd->skilltype,pd->skillval+rand()%100,tick,0);
- }
- else
+ break;
+ default:
skill_castend_damage_id(&pd->bl,&md->bl,pd->skilltype,pd->skillval,tick,0);
+ break;
+ }
pd->skillbonustimer=add_timer(gettick()+1000,pet_skillattack_timer,sd->bl.id,0);
return 0;
}
@@ -1557,9 +1588,11 @@ int read_petdb()
{
FILE *fp;
char line[1024];
- int i;
+ int nameid,i,k;
int j=0;
+ int lines;
char *filename[]={"db/pet_db.txt","db/pet_db2.txt"};
+ char *str[32],*p,*np;
memset(pet_db,0,sizeof(pet_db));
for(i=0;i<2;i++){
@@ -1570,20 +1603,21 @@ int read_petdb()
printf("can't read %s\n",filename[i]);
return -1;
}
+ lines = 0;
while(fgets(line,1020,fp)){
- int nameid,i;
- char *str[32],*p,*np;
+
+ lines++;
if(line[0] == '/' && line[1] == '/')
continue;
- for(i=0,p=line;i<20;i++){
+ for(k=0,p=line;k<20;k++){
if((np=strchr(p,','))!=NULL){
- str[i]=p;
+ str[k]=p;
*np=0;
p=np+1;
} else {
- str[i]=p;
+ str[k]=p;
p+=strlen(p);
}
}
@@ -1593,7 +1627,7 @@ int read_petdb()
continue;
//MobID,Name,JName,ItemID,EggID,AcceID,FoodID,"Fullness (1‰ñ‚̉a‚ł̖ž• “x‘‰Á—¦%)","HungryDeray (/min)","R_Hungry (‹ó• Žž‰a‚â‚èe–§“x‘‰Á—¦%)","R_Full (‚Æ‚Ä‚à–ž• Žž‰a‚â‚èe–§“xŒ¸­—¦%)","Intimate (•ߊlŽže–§“x%)","Die (Ž€–SŽže–§“xŒ¸­—¦%)","Capture (•ߊl—¦%)",(Name)
- pet_db[j].class = nameid;
+ pet_db[j].class_ = nameid;
memcpy(pet_db[j].name,str[1],24);
memcpy(pet_db[j].jname,str[2],24);
pet_db[j].itemID=atoi(str[3]);
@@ -1618,11 +1652,12 @@ int read_petdb()
pet_db[j].script = NULL;
if((np=strchr(p,'{'))==NULL)
continue;
- pet_db[j].script = parse_script(np,0);
+ pet_db[j].script = parse_script((unsigned char *) np,lines);
j++;
}
fclose(fp);
- printf("read %s done (count=%d)\n",filename[i],j);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' pets in '"CL_WHITE"%s"CL_RESET"'.\n",j,filename[i]);
+ ShowStatus(tmp_output);
}
return 0;
}
@@ -1639,7 +1674,6 @@ int do_init_pet(void)
add_timer_func_list(pet_hungry,"pet_hungry");
add_timer_func_list(pet_ai_hard,"pet_ai_hard");
add_timer_func_list(pet_skill_bonus_timer,"pet_skill_bonus_timer"); // [Valaris]
- add_timer_func_list(pet_skill_bonus_duration,"pet_skill_bonus_duration"); // [Valaris]
add_timer_func_list(pet_recovery_timer,"pet_recovery_timer"); // [Valaris]
add_timer_func_list(pet_mag_timer,"pet_mag_timer"); // [Valaris]
add_timer_func_list(pet_heal_timer,"pet_heal_timer"); // [Valaris]
@@ -1649,3 +1683,12 @@ int do_init_pet(void)
return 0;
}
+int do_final_pet(void) {
+ int i;
+ for(i = 0;i < MAX_PET_DB; i++) {
+ if(pet_db[i].script) {
+ aFree(pet_db[i].script);
+ }
+ }
+ return 0;
+}
diff --git a/src/map/pet.h b/src/map/pet.h
index 365a4490f..4d81583b1 100644
--- a/src/map/pet.h
+++ b/src/map/pet.h
@@ -2,11 +2,11 @@
#ifndef _PET_H_
#define _PET_H_
-#define MAX_PET_DB 100
+#define MAX_PET_DB 300
#define PETLOOT_SIZE 20 // [Valaris]
struct pet_db {
- int class;
+ int class_;
char name[24],jname[24];
int itemID;
int EggID;
@@ -55,15 +55,15 @@ int pet_food(struct map_session_data *sd);
int pet_lootitem_drop(struct pet_data *pd,struct map_session_data *sd);
int pet_delay_item_drop2(int tid,unsigned int tick,int id,int data);
int pet_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap);
-int pet_skill_bonus(struct map_session_data *sd,struct pet_data *pd,int type,int val,int duration,int timer,int data);
int pet_skill_bonus_timer(int tid,unsigned int tick,int id,int data); // [Valaris]
-int pet_skill_bonus_duration(int tid,unsigned int tick,int id,int data); // [Valaris]
int pet_recovery_timer(int tid,unsigned int tick,int id,int data); // [Valaris]
int pet_mag_timer(int tid,unsigned int tick,int id,int data); // [Valaris]
int pet_heal_timer(int tid,unsigned int tick,int id,int data); // [Valaris]
int pet_skillattack_timer(int tid,unsigned int tick,int id,int data); // [Valaris]
+int read_petdb();
int do_init_pet(void);
+int do_final_pet(void);
#endif
diff --git a/src/map/script.c b/src/map/script.c
index f198d42fe..9602f3505 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -14,52 +14,58 @@
#include <time.h>
-#include "socket.h"
-#include "timer.h"
-#include "malloc.h"
-#include "lock.h"
+#include "../common/socket.h"
+#include "../common/timer.h"
+#include "../common/malloc.h"
+#include "../common/lock.h"
+#include "../common/db.h"
#include "map.h"
#include "clif.h"
#include "chrif.h"
#include "itemdb.h"
#include "pc.h"
+#include "status.h"
#include "script.h"
#include "storage.h"
#include "mob.h"
#include "npc.h"
#include "pet.h"
#include "intif.h"
-#include "db.h"
#include "skill.h"
#include "chat.h"
#include "battle.h"
#include "party.h"
#include "guild.h"
-#include "lock.h"
#include "atcommand.h"
#include "log.h"
+#include "showmsg.h"
#ifdef MEMWATCH
#include "memwatch.h"
#endif
#define SCRIPT_BLOCK_SIZE 256
+
+#define FETCH(n, t) \
+ if(st->end>st->start+(n)) \
+ (t)=conv_num(st,&(st->stack->stack_data[st->start+(n)]));
+
enum { LABEL_NEXTLINE=1,LABEL_START };
-static unsigned char * script_buf;
+static unsigned char * script_buf = NULL;
static int script_pos,script_size;
char *str_buf;
int str_pos,str_size;
-static struct {
+static struct str_data_struct {
int type;
int str;
int backpatch;
int label;
- int (*func)();
+ int (*func)(struct script_state *);
int val;
int next;
-} *str_data;
+} *str_data = NULL;
int str_num=LABEL_START,str_data_size;
int str_hash[16];
@@ -78,17 +84,13 @@ struct dbt* script_get_userfunc_db(){ if(!userfunc_db) userfunc_db=strdb_init(50
int scriptlabel_final(void *k,void *d,va_list ap){ return 0; }
static char pos[11][100] = {"“ª","‘Ì","¶Žè","‰EŽè","ƒ[ƒu","ŒC","ƒAƒNƒZƒTƒŠ[1","ƒAƒNƒZƒTƒŠ[2","“ª2","“ª3","‘•’…‚µ‚Ä‚¢‚È‚¢"};
-static struct Script_Config {
- int warn_func_no_comma;
- int warn_cmd_no_comma;
- int warn_func_mismatch_paramnum;
- int warn_cmd_mismatch_paramnum;
- int check_cmdcount;
- int check_gotocount;
-} script_config;
+struct Script_Config script_config;
+
static int parse_cmd_if=0;
static int parse_cmd;
+extern int current_equip_item_index; //for New CARS Scripts. It contains Inventory Index of the EQUIP_SCRIPT caller item. [Lupus]
+
/*==========================================
* ƒ[ƒJƒ‹ƒvƒƒgƒ^ƒCƒv錾 (•K—v‚È•¨‚Ì‚Ý)
*------------------------------------------
@@ -155,6 +157,7 @@ int buildin_statusup2(struct script_state *st);
int buildin_bonus(struct script_state *st);
int buildin_bonus2(struct script_state *st);
int buildin_bonus3(struct script_state *st);
+int buildin_bonus4(struct script_state *st);
int buildin_skill(struct script_state *st);
int buildin_addtoskill(struct script_state *st); // [Valaris]
int buildin_guildskill(struct script_state *st);
@@ -193,6 +196,8 @@ int buildin_stopnpctimer(struct script_state *st);
int buildin_startnpctimer(struct script_state *st);
int buildin_setnpctimer(struct script_state *st);
int buildin_getnpctimer(struct script_state *st);
+int buildin_attachnpctimer(struct script_state *st); // [celest]
+int buildin_detachnpctimer(struct script_state *st); // [celest]
int buildin_announce(struct script_state *st);
int buildin_mapannounce(struct script_state *st);
int buildin_areaannounce(struct script_state *st);
@@ -250,6 +255,9 @@ int buildin_failedremovecards(struct script_state *st);
int buildin_marriage(struct script_state *st);
int buildin_wedding_effect(struct script_state *st);
int buildin_divorce(struct script_state *st);
+int buildin_ispartneron(struct script_state *st); // MouseJstr
+int buildin_getpartnerid(struct script_state *st); // MouseJstr
+int buildin_warppartner(struct script_state *st); // MouseJstr
int buildin_getitemname(struct script_state *st);
int buildin_makepet(struct script_state *st);
int buildin_getexp(struct script_state *st);
@@ -259,6 +267,7 @@ int buildin_clearitem(struct script_state *st);
int buildin_classchange(struct script_state *st);
int buildin_misceffect(struct script_state *st);
int buildin_soundeffect(struct script_state *st);
+int buildin_soundeffectall(struct script_state *st);
int buildin_setcastledata(struct script_state *st);
int buildin_mapwarp(struct script_state *st);
int buildin_inittimer(struct script_state *st);
@@ -274,6 +283,7 @@ int buildin_petloot(struct script_state *st); // pet looting [Valaris]
int buildin_petheal(struct script_state *st); // pet healing [Valaris]
int buildin_petmag(struct script_state *st); // pet magnificat [Valaris]
int buildin_petskillattack(struct script_state *st); // pet skill attacks [Valaris]
+int buildin_skilleffect(struct script_state *st); // skill effects [Celest]
int buildin_npcskilleffect(struct script_state *st); // skill effects for npcs [Valaris]
int buildin_specialeffect(struct script_state *st); // special effect script [Valaris]
int buildin_specialeffect2(struct script_state *st); // special effect script [Valaris]
@@ -289,6 +299,28 @@ int buildin_npcspeed(struct script_state *st); // [Valaris]
int buildin_npcwalkto(struct script_state *st); // [Valaris]
int buildin_npcstop(struct script_state *st); // [Valaris]
int buildin_getmapxy(struct script_state *st); //get map position for player/npc/pet/mob by Lorky [Lupus]
+int buildin_checkoption1(struct script_state *st); // [celest]
+int buildin_checkoption2(struct script_state *st); // [celest]
+int buildin_guildgetexp(struct script_state *st); // [celest]
+int buildin_skilluseid(struct script_state *st); // originally by Qamera [celest]
+int buildin_skillusepos(struct script_state *st); // originally by Qamera [celest]
+int buildin_logmes(struct script_state *st); // [Lupus]
+int buildin_summon(struct script_state *st); // [celest]
+int buildin_isnight(struct script_state *st); // [celest]
+int buildin_isday(struct script_state *st); // [celest]
+int buildin_isequipped(struct script_state *st); // [celest]
+int buildin_isequippedcnt(struct script_state *st); // [celest]
+int buildin_cardscnt(struct script_state *st); // [Lupus]
+int buildin_getrefine(struct script_state *st); // [celest]
+int buildin_getusersname(struct script_state *st); //jA commands added [Lupus]
+int buildin_dispbottom(struct script_state *st);
+int buildin_recovery(struct script_state *st);
+int buildin_getpetinfo(struct script_state *st);
+int buildin_checkequipedcard(struct script_state *st);
+int buildin_globalmes(struct script_state *st);
+int buildin_jump_zero(struct script_state *st);
+int buildin_select(struct script_state *st);
+int buildin_getmapmobs(struct script_state *st); //jA addition end
void push_val(struct script_stack *stack,int type,int val);
@@ -297,8 +329,15 @@ int run_func(struct script_state *st);
int mapreg_setreg(int num,int val);
int mapreg_setregstr(int num,const char *str);
+#ifdef PCRE_SUPPORT
+int buildin_defpattern(struct script_state *st); // MouseJstr
+int buildin_activatepset(struct script_state *st); // MouseJstr
+int buildin_deactivatepset(struct script_state *st); // MouseJstr
+int buildin_deletepset(struct script_state *st); // MouseJstr
+#endif
+
struct {
- int (*func)();
+ int (*func)(struct script_state *);
char *name;
char *arg;
} buildin_func[]={
@@ -363,6 +402,7 @@ struct {
{buildin_bonus,"bonus","ii"},
{buildin_bonus2,"bonus2","iii"},
{buildin_bonus3,"bonus3","iiii"},
+ {buildin_bonus4,"bonus4","iiiii"},
{buildin_skill,"skill","ii*"},
{buildin_addtoskill,"addtoskill","ii*"}, // [Valaris]
{buildin_guildskill,"guildskill","ii"},
@@ -403,6 +443,8 @@ struct {
{buildin_startnpctimer,"startnpctimer","*"},
{buildin_setnpctimer,"setnpctimer","*"},
{buildin_getnpctimer,"getnpctimer","i*"},
+ {buildin_attachnpctimer,"attachnpctimer","*"}, // attached the player id to the npc timer [Celest]
+ {buildin_detachnpctimer,"detachnpctimer","*"}, // detached the player id from the npc timer [Celest]
{buildin_announce,"announce","si"},
{buildin_mapannounce,"mapannounce","ssi"},
{buildin_areaannounce,"areaannounce","siiiisi"},
@@ -460,7 +502,10 @@ struct {
{buildin_failedremovecards,"failedremovecards","ii"},
{buildin_marriage,"marriage","s"},
{buildin_wedding_effect,"wedding",""},
- {buildin_divorce,"divorce",""},
+ {buildin_divorce,"divorce","*"},
+ {buildin_ispartneron,"ispartneron","*"},
+ {buildin_getpartnerid,"getpartnerid","*"},
+ {buildin_warppartner,"warppartner","sii"},
{buildin_getitemname,"getitemname","i"},
{buildin_makepet,"makepet","i"},
{buildin_getexp,"getexp","ii"},
@@ -470,6 +515,7 @@ struct {
{buildin_classchange,"classchange","ii"},
{buildin_misceffect,"misceffect","i"},
{buildin_soundeffect,"soundeffect","si"},
+ {buildin_soundeffectall,"soundeffectall","si"}, // SoundEffectAll [Codemaster]
{buildin_strmobinfo,"strmobinfo","ii"}, // display mob data [Valaris]
{buildin_guardian,"guardian","siisii*i"}, // summon guardians
{buildin_guardianinfo,"guardianinfo","i"}, // display guardian data [Valaris]
@@ -479,6 +525,7 @@ struct {
{buildin_petheal,"petheal","iii"}, // [Valaris]
{buildin_petmag,"petmag","iiii"}, // [Valaris]
{buildin_petskillattack,"petskillattack","iiii"}, // [Valaris]
+ {buildin_skilleffect,"skilleffect","ii"}, // skill effect [Celest]
{buildin_npcskilleffect,"npcskilleffect","iiii"}, // npc skill effect [Valaris]
{buildin_specialeffect,"specialeffect","i"}, // npc skill effect [Valaris]
{buildin_specialeffect2,"specialeffect2","i"}, // skill effect on players[Valaris]
@@ -493,16 +540,43 @@ struct {
{buildin_npctalk,"npctalk","*"}, // [Valaris]
{buildin_hasitems,"hasitems","*"}, // [Valaris]
{buildin_mobcount,"mobcount","ss"},
- {buildin_getlook,"getlook","i"},
+ {buildin_getlook,"getlook","i"},
{buildin_getsavepoint,"getsavepoint","i"},
{buildin_npcspeed,"npcspeed","i"}, // [Valaris]
{buildin_npcwalkto,"npcwalkto","ii"}, // [Valaris]
{buildin_npcstop,"npcstop",""}, // [Valaris]
{buildin_getmapxy,"getmapxy","siii*"}, //by Lorky [Lupus]
+ {buildin_checkoption1,"checkoption1","i"},
+ {buildin_checkoption2,"checkoption2","i"},
+ {buildin_guildgetexp,"guildgetexp","i"},
+ {buildin_skilluseid,"skilluseid","ii"}, // originally by Qamera [Celest]
+ {buildin_skilluseid,"doskill","ii"}, // since a lot of scripts would already use 'doskill'...
+ {buildin_skillusepos,"skillusepos","iiii"}, // [Celest]
+ {buildin_logmes,"logmes","s"}, //this command actls as MES but prints info into LOG file either SQL/TXT [Lupus]
+ {buildin_summon,"summon","si*"}, // summons a slave monster [Celest]
+ {buildin_isnight,"isnight",""}, // check whether it is night time [Celest]
+ {buildin_isday,"isday",""}, // check whether it is day time [Celest]
+ {buildin_isequipped,"isequipped","i*"}, // check whether another item/card has been equipped [Celest]
+ {buildin_isequippedcnt,"isequippedcnt","i*"}, // check how many items/cards are being equipped [Celest]
+ {buildin_cardscnt,"cardscnt","i*"}, // check how many items/cards are being equipped in the same arm [Lupus]
+ {buildin_getrefine,"getrefine",""}, // returns the refined number of the current item, or an item with index specified [celest]
+#ifdef PCRE_SUPPORT
+ {buildin_defpattern, "defpattern", "iss"}, // Define pattern to listen for [MouseJstr]
+ {buildin_activatepset, "activatepset", "i"}, // Activate a pattern set [MouseJstr]
+ {buildin_deactivatepset, "deactivatepset", "i"}, // Deactive a pattern set [MouseJstr]
+ {buildin_deletepset, "deletepset", "i"}, // Delete a pattern set [MouseJstr]
+#endif
+ {buildin_dispbottom,"dispbottom","s"}, //added from jA [Lupus]
+ {buildin_getusersname,"getusersname","*"},
+ {buildin_recovery,"recovery",""},
+ {buildin_getpetinfo,"getpetinfo","i"},
+ {buildin_checkequipedcard,"checkequipedcard","i"},
+ {buildin_jump_zero,"jump_zero","ii"}, //for future jA script compatibility
+ {buildin_select,"select","*"}, //for future jA script compatibility
+ {buildin_globalmes,"globalmes","s*"},
+ {buildin_getmapmobs,"getmapmobs","s"}, //end jA addition
{NULL,NULL,NULL},
};
-int buildin_message(struct script_state *st); // [MouseJstr]
-
enum {
C_NOP,C_POS,C_INT,C_PARAM,C_FUNC,C_STR,C_CONSTSTR,C_ARG,
@@ -536,7 +610,7 @@ static int search_str(const unsigned char *p)
int i;
i=str_hash[calc_hash(p)];
while(i){
- if(strcmp(str_buf+str_data[i].str,p)==0){
+ if(strcmp(str_buf+str_data[i].str,(char *) p)==0){
return i;
}
i=str_data[i].next;
@@ -554,14 +628,14 @@ static int add_str(const unsigned char *p)
int i;
char *lowcase;
- lowcase=strdup(p);
+ lowcase=aStrdup((char *) p);
for(i=0;lowcase[i];i++)
lowcase[i]=tolower(lowcase[i]);
- if((i=search_str(lowcase))>=0){
- free(lowcase);
+ if((i=search_str((unsigned char *) lowcase))>=0){
+ aFree(lowcase);
return i;
}
- free(lowcase);
+ aFree(lowcase);
i=calc_hash(p);
if(str_hash[i]==0){
@@ -569,7 +643,7 @@ static int add_str(const unsigned char *p)
} else {
i=str_hash[i];
for(;;){
- if(strcmp(str_buf+str_data[i].str,p)==0){
+ if(strcmp(str_buf+str_data[i].str,(char *) p)==0){
return i;
}
if(str_data[i].next==0)
@@ -580,22 +654,22 @@ static int add_str(const unsigned char *p)
}
if(str_num>=str_data_size){
str_data_size+=128;
- str_data=aRealloc(str_data,sizeof(str_data[0])*str_data_size);
+ str_data=(struct str_data_struct *) aRealloc(str_data,sizeof(str_data[0])*str_data_size);
memset(str_data + (str_data_size - 128), '\0', 128);
}
- while(str_pos+strlen(p)+1>=str_size){
+ while(str_pos+(int)strlen((char *) p)+1>=str_size){
str_size+=256;
str_buf=(char *)aRealloc(str_buf,str_size);
memset(str_buf + (str_size - 256), '\0', 256);
}
- strcpy(str_buf+str_pos,p);
+ strcpy(str_buf+str_pos, (char *) p);
str_data[str_num].type=C_NOP;
str_data[str_num].str=str_pos;
str_data[str_num].next=0;
str_data[str_num].func=NULL;
str_data[str_num].backpatch=-1;
str_data[str_num].label=-1;
- str_pos+=strlen(p)+1;
+ str_pos+=strlen( (char *) p)+1;
return str_num++;
}
@@ -608,7 +682,7 @@ static void check_script_buf(int size)
{
if(script_pos+size>=script_size){
script_size+=SCRIPT_BLOCK_SIZE;
- script_buf=(char *)aRealloc(script_buf,script_size);
+ script_buf=(unsigned char *)aRealloc(script_buf,script_size);
memset(script_buf + script_size - SCRIPT_BLOCK_SIZE, '\0',
SCRIPT_BLOCK_SIZE);
}
@@ -769,13 +843,17 @@ static void disp_error_message(const char *mes,const unsigned char *pos)
for(line=startline,p=startptr;p && *p;line++){
linestart=p;
- lineend=strchr(p,'\n');
+ lineend=(unsigned char *) strchr((char *) p,'\n');
if(lineend){
c=*lineend;
*lineend=0;
}
if(lineend==NULL || pos<lineend){
- printf("%s line %d : ",mes,line);
+ if (current_file) {
+ printf("%s in "CL_WHITE"\'%s\'"CL_RESET" line "CL_WHITE"\'%d\'"CL_RESET" : ", mes, current_file, line);
+ } else {
+ printf("%s line "CL_WHITE"\'%d\'"CL_RESET" : ", mes, line);
+ }
for(i=0;(linestart[i]!='\r') && (linestart[i]!='\n') && linestart[i];i++){
if(linestart+i!=pos)
printf("%c",linestart[i]);
@@ -819,9 +897,9 @@ unsigned char* parse_simpleexpr(unsigned char *p)
}
} else if(isdigit(*p) || ((*p=='-' || *p=='+') && isdigit(p[1]))){
char *np;
- i=strtoul(p,&np,0);
+ i=strtoul((char *) p,&np,0);
add_scripti(i);
- p=np;
+ p=(unsigned char *) np;
} else if(*p=='"'){
add_scriptc(C_STR);
p++;
@@ -848,12 +926,12 @@ unsigned char* parse_simpleexpr(unsigned char *p)
disp_error_message("unexpected character",p);
exit(1);
}
- p2=skip_word(p);
+ p2=(char *) skip_word(p);
c=*p2; *p2=0; // –¼‘O‚ðadd_str‚·‚é
l=add_str(p);
parse_cmd=l; // warn_*_mismatch_paramnum‚Ì‚½‚߂ɕK—v
- if(l==search_str("if")) // warn_cmd_no_comma‚Ì‚½‚߂ɕK—v
+ if(l== search_str((unsigned char *) "if")) // warn_cmd_no_comma‚Ì‚½‚߂ɕK—v
parse_cmd_if++;
/*
// ”pŽ~—\’è‚Ìl14/l15,‚¨‚æ‚уvƒŒƒtƒBƒbƒNƒX‚Œ‚ÌŒx
@@ -864,11 +942,12 @@ unsigned char* parse_simpleexpr(unsigned char *p)
disp_error_message("prefix 'l' is DEPRECATED. use prefix '@' instead.",p2);
}
*/
- *p2=c; p=p2;
+ *p2=c;
+ p=(unsigned char *) p2;
if(str_data[l].type!=C_FUNC && c=='['){
// array(name[i] => getelementofarray(name,i) )
- add_scriptl(search_str("getelementofarray"));
+ add_scriptl(search_str((unsigned char *) "getelementofarray"));
add_scriptc(C_ARG);
add_scriptl(l);
p=parse_subexpr(p+1,-1);
@@ -906,14 +985,14 @@ unsigned char* parse_subexpr(unsigned char *p,int limit)
p=skip_space(p);
if(*p=='-'){
- tmpp=skip_space(p+1);
+ tmpp=(char *) skip_space((unsigned char *) (p+1));
if(*tmpp==';' || *tmpp==','){
add_scriptl(LABEL_NEXTLINE);
p++;
return p;
}
}
- tmpp=p;
+ tmpp=(char *) p;
if((op=C_NEG,*p=='-') || (op=C_LNOT,*p=='!') || (op=C_NOT,*p=='~')){
p=parse_subexpr(p+1,100);
add_scriptc(op);
@@ -945,13 +1024,13 @@ unsigned char* parse_subexpr(unsigned char *p,int limit)
const char *plist[128];
if( str_data[func].type!=C_FUNC ){
- disp_error_message("expect function",tmpp);
+ disp_error_message("expect function",(unsigned char *) tmpp);
exit(0);
}
add_scriptc(C_ARG);
do {
- plist[i]=p;
+ plist[i]=(char *) p;
p=parse_subexpr(p,-1);
p=skip_space(p);
if(*p==',') p++;
@@ -961,7 +1040,7 @@ unsigned char* parse_subexpr(unsigned char *p,int limit)
p=skip_space(p);
i++;
} while(*p && *p!=')' && i<128);
- plist[i]=p;
+ plist[i]=(char *) p;
if(*(p++)!=')'){
disp_error_message("func request '(' ')'",p);
exit(1);
@@ -972,7 +1051,7 @@ unsigned char* parse_subexpr(unsigned char *p,int limit)
int j=0;
for(j=0;arg[j];j++) if(arg[j]=='*')break;
if( (arg[j]==0 && i!=j) || (arg[j]=='*' && i<j) ){
- disp_error_message("illegal number of parameters",plist[(i<j)?i:j]);
+ disp_error_message("illegal number of parameters",(unsigned char *) (plist[(i<j)?i:j]));
}
}
} else {
@@ -1029,19 +1108,19 @@ unsigned char* parse_line(unsigned char *p)
parse_cmd_if=0; // warn_cmd_no_comma‚Ì‚½‚߂ɕK—v
// ʼn‚ÍŠÖ”–¼
- p2=p;
+ p2=(char *) p;
p=parse_simpleexpr(p);
p=skip_space(p);
cmd=parse_cmd;
if( str_data[cmd].type!=C_FUNC ){
- disp_error_message("expect command",p2);
+ disp_error_message("expect command",(unsigned char *) p2);
// exit(0);
}
add_scriptc(C_ARG);
while(p && *p && *p!=';' && i<128){
- plist[i]=p;
+ plist[i]=(char *) p;
p=parse_expr(p);
p=skip_space(p);
@@ -1053,7 +1132,7 @@ unsigned char* parse_line(unsigned char *p)
p=skip_space(p);
i++;
}
- plist[i]=p;
+ plist[i]=(char *) p;
if(!p || *(p++)!=';'){
disp_error_message("need ';'",p);
exit(1);
@@ -1065,7 +1144,7 @@ unsigned char* parse_line(unsigned char *p)
int j=0;
for(j=0;arg[j];j++) if(arg[j]=='*')break;
if( (arg[j]==0 && i!=j) || (arg[j]=='*' && i<j) ){
- disp_error_message("illegal number of parameters",plist[(i<j)?i:j]);
+ disp_error_message("illegal number of parameters",(unsigned char *) (plist[(i<j)?i:j]));
}
}
@@ -1081,7 +1160,7 @@ static void add_buildin_func(void)
{
int i,n;
for(i=0;buildin_func[i].func;i++){
- n=add_str(buildin_func[i].name);
+ n=add_str((unsigned char *) buildin_func[i].name);
str_data[n].type=C_FUNC;
str_data[n].val=i;
str_data[n].func=buildin_func[i].func;
@@ -1111,7 +1190,7 @@ static void read_constdb(void)
sscanf(line,"%[A-Za-z0-9_] %d %d",name,&val,&type)>=2){
for(i=0;name[i];i++)
name[i]=tolower(name[i]);
- n=add_str(name);
+ n=add_str((const unsigned char *) name);
if(type==0)
str_data[n].type=C_INT;
else
@@ -1126,7 +1205,7 @@ static void read_constdb(void)
* ƒXƒNƒŠƒvƒg‚̉ðÍ
*------------------------------------------
*/
-unsigned char* parse_script(unsigned char *src,int line)
+char* parse_script(unsigned char *src,int line)
{
unsigned char *p,*tmpp;
int i;
@@ -1137,7 +1216,7 @@ unsigned char* parse_script(unsigned char *src,int line)
read_constdb();
}
first=0;
- script_buf=(unsigned char *)aCalloc(SCRIPT_BLOCK_SIZE,sizeof(unsigned char));
+ script_buf=(unsigned char *)aCallocA(SCRIPT_BLOCK_SIZE,sizeof(unsigned char));
script_pos=0;
script_size=SCRIPT_BLOCK_SIZE;
str_data[LABEL_NEXTLINE].type=C_NOP;
@@ -1202,7 +1281,7 @@ unsigned char* parse_script(unsigned char *src,int line)
add_scriptc(C_NOP);
script_size = script_pos;
- script_buf=(char *)aRealloc(script_buf,script_pos + 1);
+ script_buf=(unsigned char *)aRealloc(script_buf,script_pos + 1);
// –¢‰ðŒˆ‚̃‰ƒxƒ‹‚ð‰ðŒˆ
for(i=LABEL_START;i<str_num;i++){
@@ -1229,7 +1308,7 @@ unsigned char* parse_script(unsigned char *src,int line)
printf("\n");
#endif
- return script_buf;
+ return (char *) script_buf;
}
//
@@ -1364,6 +1443,11 @@ static int set_reg(struct map_session_data *sd,int num,char *name,void *v)
return 0;
}
+int set_var(struct map_session_data *sd, char *name, void *val)
+{
+ return set_reg(sd, add_str((unsigned char *) name), name, val);
+}
+
/*==========================================
* •¶Žš—ñ‚ւ̕ϊ·
*------------------------------------------
@@ -1373,7 +1457,7 @@ char* conv_str(struct script_state *st,struct script_data *data)
get_val(st,data);
if(data->type==C_INT){
char *buf;
- buf=(char *)aCalloc(16,sizeof(char));
+ buf=(char *)aCallocA(16,sizeof(char));
sprintf(buf,"%d",data->u.num);
data->type=C_STR;
data->u.str=buf;
@@ -1399,7 +1483,7 @@ int conv_num(struct script_state *st,struct script_data *data)
p=data->u.str;
data->u.num = atoi(p);
if(data->type==C_STR)
- free(p);
+ aFree(p);
data->type=C_INT;
}
return data->u.num;
@@ -1441,7 +1525,7 @@ void push_str(struct script_stack *stack,int type,unsigned char *str)
// if(battle_config.etc_log)
// printf("push (%d,%x)-> %d\n",type,str,stack->sp);
stack->stack_data[stack->sp].type=type;
- stack->stack_data[stack->sp].u.str=str;
+ stack->stack_data[stack->sp].u.str=(char *) str;
stack->sp++;
}
@@ -1453,10 +1537,10 @@ void push_copy(struct script_stack *stack,int pos)
{
switch(stack->stack_data[pos].type){
case C_CONSTSTR:
- push_str(stack,C_CONSTSTR,stack->stack_data[pos].u.str);
+ push_str(stack,C_CONSTSTR,(unsigned char *) stack->stack_data[pos].u.str);
break;
case C_STR:
- push_str(stack,C_STR,strdup(stack->stack_data[pos].u.str));
+ push_str(stack,C_STR,(unsigned char *) aStrdup(stack->stack_data[pos].u.str));
break;
default:
push_val(stack,stack->stack_data[pos].type,stack->stack_data[pos].u.num);
@@ -1473,7 +1557,7 @@ void pop_stack(struct script_stack* stack,int start,int end)
int i;
for(i=start;i<end;i++){
if(stack->stack_data[i].type==C_STR){
- free(stack->stack_data[i].u.str);
+ aFree(stack->stack_data[i].u.str);
}
}
if(stack->sp>end){
@@ -1505,7 +1589,7 @@ int buildin_goto(struct script_state *st)
int pos;
if( st->stack->stack_data[st->start+2].type!=C_POS ){
- printf("script: goto: not label !\n");
+ printf("script: goto: not label!\n");
st->state=END;
return 0;
}
@@ -1525,7 +1609,7 @@ int buildin_callfunc(struct script_state *st)
char *scr;
char *str=conv_str(st,& (st->stack->stack_data[st->start+2]));
- if( (scr=strdb_search(script_get_userfunc_db(),str)) ){
+ if( (scr=(char *) strdb_search(script_get_userfunc_db(),str)) ){
int i,j;
for(i=st->start+3,j=0;i<st->end;i++,j++)
push_copy(st->stack,i);
@@ -1641,7 +1725,7 @@ int buildin_menu(struct script_state *st)
char *buf;
int len,i;
struct map_session_data *sd;
-
+
sd=script_rid2sd(st);
if(sd->state.menu_or_input==0){
@@ -1651,21 +1735,21 @@ int buildin_menu(struct script_state *st)
conv_str(st,& (st->stack->stack_data[i]));
len+=strlen(st->stack->stack_data[i].u.str)+1;
}
- buf=(char *)aCalloc(len,sizeof(char));
+ buf=(char *)aCallocA(len+1,sizeof(char));
buf[0]=0;
for(i=st->start+2,len=0;i<st->end;i+=2){
strcat(buf,st->stack->stack_data[i].u.str);
strcat(buf,":");
}
clif_scriptmenu(script_rid2sd(st),st->oid,buf);
- free(buf);
+ aFree(buf);
} else if(sd->npc_menu==0xff){ // cansel
sd->state.menu_or_input=0;
st->state=END;
} else { // goto“®ì
// ragemuŒÝŠ·‚Ì‚½‚ß
- pc_setreg(sd,add_str("l15"),sd->npc_menu);
- pc_setreg(sd,add_str("@menu"),sd->npc_menu);
+ pc_setreg(sd,add_str((unsigned char *) "l15"),sd->npc_menu);
+ pc_setreg(sd,add_str((unsigned char *) "@menu"),sd->npc_menu);
sd->state.menu_or_input=0;
if(sd->npc_menu>0 && sd->npc_menu<(st->end-st->start)/2){
int pos;
@@ -1688,21 +1772,23 @@ int buildin_menu(struct script_state *st)
*/
int buildin_rand(struct script_state *st)
{
- int range,min,max;
+ int range;
- if(st->end>st->start+3){
- min=conv_num(st,& (st->stack->stack_data[st->start+2]));
- max=conv_num(st,& (st->stack->stack_data[st->start+3]));
- if(max<min){
- int tmp;
- tmp=min;
- min=max;
- max=tmp;
+ if (st->end > st->start+3){
+ int min, max;
+ min = conv_num(st,& (st->stack->stack_data[st->start+2]));
+ max = conv_num(st,& (st->stack->stack_data[st->start+3]));
+ if (max < min){
+ int tmp = min;
+ min = max;
+ max = tmp;
}
- range=max-min+1;
+ range = max - min + 1;
+ if (range == 0) range = 1;
push_val(st->stack,C_INT,rand()%range+min);
} else {
- range=conv_num(st,& (st->stack->stack_data[st->start+2]));
+ range = conv_num(st,& (st->stack->stack_data[st->start+2]));
+ if (range == 0) range = 1;
push_val(st->stack,C_INT,rand()%range);
}
return 0;
@@ -1846,7 +1932,7 @@ int buildin_input(struct script_state *st)
{
struct map_session_data *sd=NULL;
int num=(st->end>st->start+2)?st->stack->stack_data[st->start+2].u.num:0;
- char *name=(st->end>st->start+2)?str_buf+str_data[num&0x00ffffff].str:"";
+ char *name=(char *) ((st->end>st->start+2)?str_buf+str_data[num&0x00ffffff].str:"");
// char prefix=*name;
char postfix=name[strlen(name)-1];
@@ -1877,7 +1963,7 @@ int buildin_input(struct script_state *st)
set_reg(sd,num,name,(void*)sd->npc_amount);
} else {
// ragemuŒÝŠ·‚Ì‚½‚ß
- pc_setreg(sd,add_str("l14"),sd->npc_amount);
+ pc_setreg(sd,add_str((unsigned char *) "l14"),sd->npc_amount);
}
}
} else {
@@ -2102,7 +2188,7 @@ int buildin_deletearray(struct script_state *st)
}
for(;i<(128-(num>>24));i++){
if( postfix!='$' ) set_reg(sd,num+(i<<24),name, 0);
- if( postfix=='$' ) set_reg(sd,num+(i<<24),name, "");
+ if( postfix=='$' ) set_reg(sd,num+(i<<24),name, (void *) "");
}
return 0;
}
@@ -2274,7 +2360,7 @@ int buildin_checkweight(struct script_state *st)
*/
int buildin_getitem(struct script_state *st)
{
- int nameid,amount,flag = 0;
+ int nameid,nameidsrc,amount,flag = 0;
struct item item_tmp;
struct map_session_data *sd;
struct script_data *data;
@@ -2296,12 +2382,12 @@ int buildin_getitem(struct script_state *st)
return 0; //return if amount <=0, skip the useles iteration
}
//Violet Box, Blue Box, etc - random item pick
- if(nameid<0) { // ƒ‰ƒ“ƒ_ƒ€
+ if((nameidsrc = nameid)<0) { // Save real ID of the source Box [Lupus]
nameid=itemdb_searchrandomid(-nameid);
- #ifndef TXT_ONLY
+
if(log_config.present > 0)
- log_present(sd, -nameid, nameid);
- #endif //USE_SQL
+ log_present(sd, -nameidsrc, nameid); //fixed missing ID by Lupus
+
flag = 1;
}
@@ -2318,7 +2404,8 @@ int buildin_getitem(struct script_state *st)
return 0;
if((flag = pc_additem(sd,&item_tmp,amount))) {
clif_additem(sd,0,0,flag);
- map_addflooritem(&item_tmp,amount,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0);
+ if(!pc_candrop(sd,nameid))
+ map_addflooritem(&item_tmp,amount,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0);
}
}
@@ -2499,7 +2586,7 @@ int buildin_delitem(struct script_state *st)
if(sd->inventory_data[i]->type==7 && sd->status.inventory[i].card[0] == (short)0xff00 && search_petDB_index(nameid, PET_EGG) >= 0 ){
intif_delete_petdata(*((long *)(&sd->status.inventory[i].card[1])));
//clear egg flag. so it won't be put in IMPORTANT items (eggs look like item with 2 cards ^_^)
- sd->status.inventory[i].card[1] = sd->status.inventory[i].card[0] = 0;
+ sd->status.inventory[i].card[1] = sd->status.inventory[i].card[0] = 0;
//now this egg'll be deleted as a common unimportant item
}
//is this item important? does it have cards? or Player's name? or Refined/Upgraded
@@ -2528,7 +2615,7 @@ int buildin_delitem(struct script_state *st)
continue;
if(sd->status.inventory[i].amount>=amount){
- pc_delitem(sd,i,amount,0);
+ pc_delitem(sd,i,amount,0);
return 0; //we deleted exact amount of items. now exit
} else {
amount-=sd->status.inventory[i].amount;
@@ -2604,7 +2691,7 @@ char *buildin_getpartyname_sub(int party_id)
if(p!=NULL){
char *buf;
- buf=(char *)aCalloc(24,sizeof(char));
+ buf=(char *)aCallocA(24,sizeof(char));
strcpy(buf,p->name);
return buf;
}
@@ -2619,9 +2706,9 @@ int buildin_getpartyname(struct script_state *st)
party_id=conv_num(st,& (st->stack->stack_data[st->start+2]));
name=buildin_getpartyname_sub(party_id);
if(name!=0)
- push_str(st->stack,C_STR,name);
+ push_str(st->stack,C_STR,(unsigned char *)name);
else
- push_str(st->stack,C_CONSTSTR,"null");
+ push_str(st->stack,C_CONSTSTR, (unsigned char *) "null");
return 0;
}
@@ -2641,12 +2728,12 @@ int buildin_getpartymember(struct script_state *st)
for(i=0;i<MAX_PARTY;i++){
if(p->member[i].account_id){
// printf("name:%s %d\n",p->member[i].name,i);
- mapreg_setregstr(add_str("$@partymembername$")+(i<<24),p->member[i].name);
+ mapreg_setregstr(add_str((unsigned char *) "$@partymembername$")+(i<<24),p->member[i].name);
j++;
}
}
}
- mapreg_setreg(add_str("$@partymembercount"),j);
+ mapreg_setreg(add_str((unsigned char *) "$@partymembercount"),j);
return 0;
}
@@ -2661,7 +2748,7 @@ char *buildin_getguildname_sub(int guild_id)
if(g!=NULL){
char *buf;
- buf=(char *)aCalloc(24,sizeof(char));
+ buf=(char *)aCallocA(24,sizeof(char));
strcpy(buf,g->name);
return buf;
}
@@ -2673,9 +2760,9 @@ int buildin_getguildname(struct script_state *st)
int guild_id=conv_num(st,& (st->stack->stack_data[st->start+2]));
name=buildin_getguildname_sub(guild_id);
if(name!=0)
- push_str(st->stack,C_STR,name);
+ push_str(st->stack,C_STR,(unsigned char *) name);
else
- push_str(st->stack,C_CONSTSTR,"null");
+ push_str(st->stack,C_CONSTSTR,(unsigned char *) "null");
return 0;
}
@@ -2690,7 +2777,7 @@ char *buildin_getguildmaster_sub(int guild_id)
if(g!=NULL){
char *buf;
- buf=(char *)aCalloc(24,sizeof(char));
+ buf=(char *)aCallocA(24,sizeof(char));
strncpy(buf,g->master, 23);
return buf;
}
@@ -2703,9 +2790,9 @@ int buildin_getguildmaster(struct script_state *st)
int guild_id=conv_num(st,& (st->stack->stack_data[st->start+2]));
master=buildin_getguildmaster_sub(guild_id);
if(master!=0)
- push_str(st->stack,C_STR,master);
+ push_str(st->stack,C_STR,(unsigned char *) master);
else
- push_str(st->stack,C_CONSTSTR,"null");
+ push_str(st->stack,C_CONSTSTR,(unsigned char *) "null");
return 0;
}
@@ -2740,25 +2827,25 @@ int buildin_strcharinfo(struct script_state *st)
num=conv_num(st,& (st->stack->stack_data[st->start+2]));
if(num==0){
char *buf;
- buf=(char *)aCalloc(24,sizeof(char));
+ buf=(char *)aCallocA(24,sizeof(char));
strncpy(buf,sd->status.name, 23);
- push_str(st->stack,C_STR,buf);
+ push_str(st->stack,C_STR,(unsigned char *) buf);
}
if(num==1){
char *buf;
buf=buildin_getpartyname_sub(sd->status.party_id);
if(buf!=0)
- push_str(st->stack,C_STR,buf);
+ push_str(st->stack,C_STR,(unsigned char *) buf);
else
- push_str(st->stack,C_CONSTSTR,"");
+ push_str(st->stack,C_CONSTSTR,(unsigned char *) "");
}
if(num==2){
char *buf;
buf=buildin_getguildname_sub(sd->status.guild_id);
if(buf!=0)
- push_str(st->stack,C_STR,buf);
+ push_str(st->stack,C_STR,(unsigned char *) buf);
else
- push_str(st->stack,C_CONSTSTR,"");
+ push_str(st->stack,C_CONSTSTR,(unsigned char *) "");
}
return 0;
@@ -2807,7 +2894,7 @@ int buildin_getequipname(struct script_state *st)
struct item_data* item;
char *buf;
- buf=(char *)aCalloc(64,sizeof(char));
+ buf=(char *)aCallocA(64,sizeof(char));
sd=script_rid2sd(st);
num=conv_num(st,& (st->stack->stack_data[st->start+2]));
i=pc_checkequip(sd,equip[num-1]);
@@ -2820,7 +2907,7 @@ int buildin_getequipname(struct script_state *st)
}else{
sprintf(buf,"%s-[%s]",pos[num-1],pos[10]);
}
- push_str(st->stack,C_STR,buf);
+ push_str(st->stack,C_STR,(unsigned char *) buf);
return 0;
}
@@ -2833,9 +2920,9 @@ int buildin_getbrokenid(struct script_state *st)
{
int i,num,id=0,brokencounter=0;
struct map_session_data *sd;
-
+
sd=script_rid2sd(st);
-
+
num=conv_num(st,& (st->stack->stack_data[st->start+2]));
for(i=0; i<MAX_INVENTORY; i++) {
if(sd->status.inventory[i].attribute==1){
@@ -2846,7 +2933,7 @@ int buildin_getbrokenid(struct script_state *st)
}
}
}
-
+
push_val(st->stack,C_INT,id);
return 0;
@@ -2864,7 +2951,7 @@ int buildin_repair(struct script_state *st)
sd=script_rid2sd(st);
-
+
num=conv_num(st,& (st->stack->stack_data[st->start+2]));
for(i=0; i<MAX_INVENTORY; i++) {
if(sd->status.inventory[i].attribute==1){
@@ -2916,10 +3003,13 @@ int buildin_getequipisenableref(struct script_state *st)
num=conv_num(st,& (st->stack->stack_data[st->start+2]));
sd=script_rid2sd(st);
i=pc_checkequip(sd,equip[num-1]);
- if(i >= 0 && num<7 && sd->inventory_data[i] && (num!=1
+ if(i >= 0 && num<7 && sd->inventory_data[i] && !sd->inventory_data[i]->flag.no_refine)
+ // replaced by Celest
+ /*(num!=1
|| sd->inventory_data[i]->def > 1
|| (sd->inventory_data[i]->def==1 && sd->inventory_data[i]->equip_script==NULL)
- || (sd->inventory_data[i]->def<=0 && sd->inventory_data[i]->equip_script!=NULL)))
+ || (sd->inventory_data[i]->def<=0 && sd->inventory_data[i]->equip_script!=NULL)))*/
+
{
push_val(st->stack,C_INT,1);
} else {
@@ -3002,7 +3092,7 @@ int buildin_getequippercentrefinery(struct script_state *st)
sd=script_rid2sd(st);
i=pc_checkequip(sd,equip[num-1]);
if(i >= 0)
- push_val(st->stack,C_INT,pc_percentrefinery(sd,&sd->status.inventory[i]));
+ push_val(st->stack,C_INT,status_percentrefinery(sd,&sd->status.inventory[i]));
else
push_val(st->stack,C_INT,0);
@@ -3024,13 +3114,11 @@ int buildin_successrefitem(struct script_state *st)
if(i >= 0) {
ep=sd->status.inventory[i].equip;
- #ifndef TXT_ONLY
if(log_config.refine > 0)
log_refine(sd, i, 1);
- #endif //USE_SQL
sd->status.inventory[i].refine++;
- pc_unequipitem(sd,i,0, BF_NORMAL);
+ pc_unequipitem(sd,i,2);
clif_refine(sd->fd,sd,0,i,sd->status.inventory[i].refine);
clif_delitem(sd,i,1);
clif_additem(sd,i,1,0);
@@ -3054,13 +3142,11 @@ int buildin_failedrefitem(struct script_state *st)
sd=script_rid2sd(st);
i=pc_checkequip(sd,equip[num-1]);
if(i >= 0) {
- #ifndef TXT_ONLY
if(log_config.refine > 0)
log_refine(sd, i, 0);
- #endif //USE_SQL
sd->status.inventory[i].refine = 0;
- pc_unequipitem(sd,i,0, BF_NORMAL);
+ pc_unequipitem(sd,i,3);
// ¸˜Bޏ”sƒGƒtƒFƒNƒg‚̃pƒPƒbƒg
clif_refine(sd->fd,sd,1,i,sd->status.inventory[i].refine);
pc_delitem(sd,i,1,0);
@@ -3153,6 +3239,22 @@ int buildin_bonus3(struct script_state *st)
return 0;
}
+
+int buildin_bonus4(struct script_state *st)
+{
+ int type,type2,type3,type4,val;
+ struct map_session_data *sd;
+
+ type=conv_num(st,& (st->stack->stack_data[st->start+2]));
+ type2=conv_num(st,& (st->stack->stack_data[st->start+3]));
+ type3=conv_num(st,& (st->stack->stack_data[st->start+4]));
+ type4=conv_num(st,& (st->stack->stack_data[st->start+5]));
+ val=conv_num(st,& (st->stack->stack_data[st->start+6]));
+ sd=script_rid2sd(st);
+ pc_bonus4(sd,type,type2,type3,type4,val);
+
+ return 0;
+}
/*==========================================
* ƒXƒLƒ‹Š“¾
*------------------------------------------
@@ -3219,15 +3321,15 @@ int buildin_getskilllv(struct script_state *st)
return 0;
}
/*==========================================
- * getgdskilllv(Guild_ID, Skill_ID);
- * skill_id = 10000 : GD_APPROVAL
- * 10001 : GD_KAFRACONTACT
- * 10002 : GD_GUARDIANRESEARCH
- * 10003 : GD_GUARDUP
- * 10004 : GD_EXTENSION
+ * getgdskilllv(Guild_ID, Skill_ID);
+ * skill_id = 10000 : GD_APPROVAL
+ * 10001 : GD_KAFRACONTACT
+ * 10002 : GD_GUARDIANRESEARCH
+ * 10003 : GD_GUARDUP
+ * 10004 : GD_EXTENSION
*------------------------------------------
*/
-int buildin_getgdskilllv(struct script_state *st)
+int buildin_getgdskilllv(struct script_state *st)
{
int guild_id=conv_num(st,& (st->stack->stack_data[st->start+2]));
int skill_id=conv_num(st,& (st->stack->stack_data[st->start+3]));
@@ -3299,6 +3401,46 @@ int buildin_checkoption(struct script_state *st)
return 0;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
+int buildin_checkoption1(struct script_state *st)
+{
+ int type;
+ struct map_session_data *sd;
+
+ type=conv_num(st,& (st->stack->stack_data[st->start+2]));
+ sd=script_rid2sd(st);
+
+ if(sd->opt1 & type){
+ push_val(st->stack,C_INT,1);
+ } else {
+ push_val(st->stack,C_INT,0);
+ }
+
+ return 0;
+}
+/*==========================================
+ *
+ *------------------------------------------
+ */
+int buildin_checkoption2(struct script_state *st)
+{
+ int type;
+ struct map_session_data *sd;
+
+ type=conv_num(st,& (st->stack->stack_data[st->start+2]));
+ sd=script_rid2sd(st);
+
+ if(sd->opt2 & type){
+ push_val(st->stack,C_INT,1);
+ } else {
+ push_val(st->stack,C_INT,0);
+ }
+
+ return 0;
+}
/*==========================================
*
@@ -3524,11 +3666,11 @@ int buildin_gettimestr(struct script_state *st)
fmtstr=conv_str(st,& (st->stack->stack_data[st->start+2]));
maxlen=conv_num(st,& (st->stack->stack_data[st->start+3]));
- tmpstr=(char *)aCalloc(maxlen+1,sizeof(char));
+ tmpstr=(char *)aCallocA(maxlen+1,sizeof(char));
strftime(tmpstr,maxlen,fmtstr,localtime(&now));
tmpstr[maxlen]='\0';
- push_str(st->stack,C_STR,tmpstr);
+ push_str(st->stack,C_STR,(unsigned char *) tmpstr);
return 0;
}
@@ -3608,11 +3750,11 @@ int buildin_makepet(struct script_state *st)
if (pet_id < 0)
pet_id = search_petDB_index(id, PET_EGG);
if (pet_id >= 0 && sd) {
- sd->catch_target_class = pet_db[pet_id].class;
+ sd->catch_target_class = pet_db[pet_id].class_;
intif_create_pet(
sd->status.account_id, sd->status.char_id,
- pet_db[pet_id].class, mob_db[pet_db[pet_id].class].lv,
- pet_db[pet_id].EggID, 0, pet_db[pet_id].intimate,
+ (short)pet_db[pet_id].class_, (short)mob_db[pet_db[pet_id].class_].lv,
+ (short)pet_db[pet_id].EggID, 0, (short)pet_db[pet_id].intimate,
100, 0, 1, pet_db[pet_id].jname);
}
@@ -3638,24 +3780,42 @@ int buildin_getexp(struct script_state *st)
}
/*==========================================
+ * Gain guild exp [Celest]
+ *------------------------------------------
+ */
+int buildin_guildgetexp(struct script_state *st)
+{
+ struct map_session_data *sd = script_rid2sd(st);
+ int exp;
+
+ exp = conv_num(st,& (st->stack->stack_data[st->start+2]));
+ if(exp < 0)
+ return 0;
+ if(sd && sd->status.guild_id > 0)
+ guild_getexp (sd, exp);
+
+ return 0;
+}
+
+/*==========================================
* ƒ‚ƒ“ƒXƒ^[”­¶
*------------------------------------------
*/
int buildin_monster(struct script_state *st)
{
- int class,amount,x,y;
+ int class_,amount,x,y;
char *str,*map,*event="";
map =conv_str(st,& (st->stack->stack_data[st->start+2]));
x =conv_num(st,& (st->stack->stack_data[st->start+3]));
y =conv_num(st,& (st->stack->stack_data[st->start+4]));
str =conv_str(st,& (st->stack->stack_data[st->start+5]));
- class=conv_num(st,& (st->stack->stack_data[st->start+6]));
+ class_=conv_num(st,& (st->stack->stack_data[st->start+6]));
amount=conv_num(st,& (st->stack->stack_data[st->start+7]));
if( st->end>st->start+8 )
event=conv_str(st,& (st->stack->stack_data[st->start+8]));
- mob_once_spawn(map_id2sd(st->rid),map,x,y,str,class,amount,event);
+ mob_once_spawn(map_id2sd(st->rid),map,x,y,str,class_,amount,event);
return 0;
}
/*==========================================
@@ -3664,7 +3824,7 @@ int buildin_monster(struct script_state *st)
*/
int buildin_areamonster(struct script_state *st)
{
- int class,amount,x0,y0,x1,y1;
+ int class_,amount,x0,y0,x1,y1;
char *str,*map,*event="";
map =conv_str(st,& (st->stack->stack_data[st->start+2]));
@@ -3673,12 +3833,12 @@ int buildin_areamonster(struct script_state *st)
x1 =conv_num(st,& (st->stack->stack_data[st->start+5]));
y1 =conv_num(st,& (st->stack->stack_data[st->start+6]));
str =conv_str(st,& (st->stack->stack_data[st->start+7]));
- class=conv_num(st,& (st->stack->stack_data[st->start+8]));
+ class_=conv_num(st,& (st->stack->stack_data[st->start+8]));
amount=conv_num(st,& (st->stack->stack_data[st->start+9]));
if( st->end>st->start+10 )
event=conv_str(st,& (st->stack->stack_data[st->start+10]));
- mob_once_spawn_area(map_id2sd(st->rid),map,x0,y0,x1,y1,str,class,amount,event);
+ mob_once_spawn_area(map_id2sd(st->rid),map,x0,y0,x1,y1,str,class_,amount,event);
return 0;
}
/*==========================================
@@ -3808,7 +3968,7 @@ int buildin_initnpctimer(struct script_state *st)
nd=(struct npc_data *)map_id2bl(st->oid);
npc_settimerevent_tick(nd,0);
- npc_timerevent_start(nd);
+ npc_timerevent_start(nd, st->rid);
return 0;
}
/*==========================================
@@ -3823,7 +3983,7 @@ int buildin_startnpctimer(struct script_state *st)
else
nd=(struct npc_data *)map_id2bl(st->oid);
- npc_timerevent_start(nd);
+ npc_timerevent_start(nd, st->rid);
return 0;
}
/*==========================================
@@ -3882,6 +4042,46 @@ int buildin_setnpctimer(struct script_state *st)
}
/*==========================================
+ * attaches the player rid to the timer [Celest]
+ *------------------------------------------
+ */
+int buildin_attachnpctimer(struct script_state *st)
+{
+ struct map_session_data *sd;
+ struct npc_data *nd;
+
+ nd=(struct npc_data *)map_id2bl(st->oid);
+ if( st->end > st->start+2 ) {
+ char *name = conv_str(st,& (st->stack->stack_data[st->start+2]));
+ sd=map_nick2sd(name);
+ } else {
+ sd = script_rid2sd(st);
+ }
+
+ if (sd==NULL)
+ return 0;
+
+ nd->u.scr.rid = sd->bl.id;
+ return 0;
+}
+
+/*==========================================
+ * detaches a player rid from the timer [Celest]
+ *------------------------------------------
+ */
+int buildin_detachnpctimer(struct script_state *st)
+{
+ struct npc_data *nd;
+ if( st->end > st->start+2 )
+ nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+2])));
+ else
+ nd=(struct npc_data *)map_id2bl(st->oid);
+
+ nd->u.scr.rid = 0;
+ return 0;
+}
+
+/*==========================================
* “V‚̺ƒAƒiƒEƒ“ƒX
*------------------------------------------
*/
@@ -3971,6 +4171,25 @@ int buildin_getusers(struct script_state *st)
return 0;
}
/*==========================================
+ * Works like @WHO - displays all online users names in window
+ *------------------------------------------
+ */
+int buildin_getusersname(struct script_state *st)
+{
+ struct map_session_data *pl_sd = NULL;
+ int i=0,disp_num=1;
+
+ for (i=0;i<fd_max;i++)
+ if(session[i] && (pl_sd=(struct map_session_data *) session[i]->session_data) && pl_sd->state.auth){
+ if( !(battle_config.hide_GM_session && pc_isGM(pl_sd)) ){
+ if((disp_num++)%10==0)
+ clif_scriptnext(script_rid2sd(st),st->oid);
+ clif_scriptmes(script_rid2sd(st),st->oid,pl_sd->status.name);
+ }
+ }
+ return 0;
+}
+/*==========================================
* ƒ}ƒbƒvŽw’胆[ƒU[”Š“¾
*------------------------------------------
*/
@@ -4146,9 +4365,12 @@ int buildin_sc_start(struct script_state *st)
bl = map_id2bl(conv_num(st,& (st->stack->stack_data[st->start+5])));
else
bl = map_id2bl(st->rid);
- if(bl->type == BL_PC && ((struct map_session_data *)bl)->state.potionpitcher_flag)
- bl = map_id2bl(((struct map_session_data *)bl)->skilltarget);
- skill_status_change_start(bl,type,val1,0,0,0,tick,0);
+
+ if (bl != 0) {
+ if(bl->type == BL_PC && ((struct map_session_data *)bl)->state.potionpitcher_flag)
+ bl = map_id2bl(((struct map_session_data *)bl)->skilltarget);
+ status_change_start(bl,type,val1,0,0,0,tick,0);
+ }
return 0;
}
@@ -4171,7 +4393,7 @@ int buildin_sc_start2(struct script_state *st)
if(bl->type == BL_PC && ((struct map_session_data *)bl)->state.potionpitcher_flag)
bl = map_id2bl(((struct map_session_data *)bl)->skilltarget);
if(rand()%10000 < per)
- skill_status_change_start(bl,type,val1,0,0,0,tick,0);
+ status_change_start(bl,type,val1,0,0,0,tick,0);
return 0;
}
@@ -4187,7 +4409,7 @@ int buildin_sc_end(struct script_state *st)
bl = map_id2bl(st->rid);
if(bl->type == BL_PC && ((struct map_session_data *)bl)->state.potionpitcher_flag)
bl = map_id2bl(((struct map_session_data *)bl)->skilltarget);
- skill_status_change_end(bl,type,-1);
+ status_change_end(bl,type,-1);
// if(battle_config.etc_log)
// printf("sc_end : %d %d\n",st->rid,type);
return 0;
@@ -4199,8 +4421,7 @@ int buildin_sc_end(struct script_state *st)
int buildin_getscrate(struct script_state *st)
{
struct block_list *bl;
- int sc_def=100,sc_def_mdef2,sc_def_vit2,sc_def_int2,sc_def_luk2;
- int type,rate,luk;
+ int sc_def,type,rate;
type=conv_num(st,& (st->stack->stack_data[st->start+2]));
rate=conv_num(st,& (st->stack->stack_data[st->start+3]));
@@ -4209,22 +4430,9 @@ int buildin_getscrate(struct script_state *st)
else
bl = map_id2bl(st->rid);
- luk = battle_get_luk(bl);
- sc_def_mdef2=100 - (3 + battle_get_mdef(bl) + luk/3);
- sc_def_vit2=100 - (3 + battle_get_vit(bl) + luk/3);
- sc_def_int2=100 - (3 + battle_get_int(bl) + luk/3);
- sc_def_luk2=100 - (3 + luk);
-
- if(type==SC_STONE || type==SC_FREEZE)
- sc_def=sc_def_mdef2;
- else if(type==SC_STAN || type==SC_POISON || type==SC_SILENCE)
- sc_def=sc_def_vit2;
- else if(type==SC_SLEEP || type==SC_CONFUSION || type==SC_BLIND)
- sc_def=sc_def_int2;
- else if(type==SC_CURSE)
- sc_def=sc_def_luk2;
-
- rate=rate*sc_def/100;
+ sc_def = status_get_sc_def(bl,type);
+
+ rate = rate * sc_def / 100;
push_val(st->stack,C_INT,rate);
return 0;
@@ -4347,13 +4555,13 @@ int buildin_changesex(struct script_state *st) {
if (sd->status.sex == 0) {
sd->status.sex = 1;
sd->sex = 1;
- if (sd->status.class == 20 || sd->status.class == 4021)
- sd->status.class -= 1;
+ if (sd->status.class_ == 20 || sd->status.class_ == 4021)
+ sd->status.class_ -= 1;
} else if (sd->status.sex == 1) {
sd->status.sex = 0;
sd->sex = 0;
- if(sd->status.class == 19 || sd->status.class == 4020)
- sd->status.class += 1;
+ if(sd->status.class_ == 19 || sd->status.class_ == 4020)
+ sd->status.class_ += 1;
}
chrif_char_ask_name(-1, sd->status.name, 5, 0, 0, 0, 0, 0, 0); // type: 5 - changesex
chrif_save(sd);
@@ -4395,6 +4603,29 @@ int buildin_waitingroom(struct script_state *st)
return 0;
}
/*==========================================
+ * Works like 'announce' but outputs in the common chat window
+ *------------------------------------------
+ */
+int buildin_globalmes(struct script_state *st)
+{
+ struct block_list *bl = map_id2bl(st->oid);
+ struct npc_data *nd = (struct npc_data *)bl;
+ char *name=NULL,*mes;
+
+ mes=conv_str(st,& (st->stack->stack_data[st->start+2])); // ƒƒbƒZ[ƒW‚̎擾
+ if(mes==NULL) return 0;
+
+ if(st->end>st->start+3){ // NPC–¼‚̎擾(123#456)
+ name=conv_str(st,& (st->stack->stack_data[st->start+3]));
+ } else {
+ name=nd->name;
+ }
+
+ npc_globalmessage(name,mes); // ƒOƒ[ƒoƒ‹ƒƒbƒZ[ƒW‘—M
+
+ return 0;
+}
+/*==========================================
* npcƒ`ƒƒƒbƒgíœ
*------------------------------------------
*/
@@ -4496,13 +4727,13 @@ int buildin_getwaitingroomstate(struct script_state *st)
case 33: val=(cd->users >= cd->trigger); break;
case 4:
- push_str(st->stack,C_CONSTSTR,cd->title);
+ push_str(st->stack,C_CONSTSTR,(unsigned char *) cd->title);
return 0;
case 5:
- push_str(st->stack,C_CONSTSTR,cd->pass);
+ push_str(st->stack,C_CONSTSTR,(unsigned char *) cd->pass);
return 0;
case 16:
- push_str(st->stack,C_CONSTSTR,cd->npc_event);
+ push_str(st->stack,C_CONSTSTR,(unsigned char *) cd->npc_event);
return 0;
}
push_val(st->stack,C_INT,val);
@@ -4534,7 +4765,7 @@ int buildin_warpwaitingpc(struct script_state *st)
for(i=0;i<n;i++){
struct map_session_data *sd=cd->usersd[0]; // ƒŠƒXƒg擪‚ÌPC‚ðŽŸX‚ÉB
- mapreg_setreg(add_str("$@warpwaitingpc")+(i<<24),sd->bl.id);
+ mapreg_setreg(add_str((unsigned char *) "$@warpwaitingpc")+(i<<24),sd->bl.id);
if(strcmp(str,"Random")==0)
pc_randomwarp(sd,3);
@@ -4547,7 +4778,7 @@ int buildin_warpwaitingpc(struct script_state *st)
}else
pc_setpos(sd,str,x,y,0);
}
- mapreg_setreg(add_str("$@warpwaitingpcnum"),n);
+ mapreg_setreg(add_str((unsigned char *) "$@warpwaitingpcnum"),n);
return 0;
}
/*==========================================
@@ -4790,7 +5021,7 @@ int buildin_pvpon(struct script_state *st)
return 0;
for(i=0;i<fd_max;i++){ //l”•ªƒ‹[ƒv
- if(session[i] && (pl_sd=session[i]->session_data) && pl_sd->state.auth){
+ if(session[i] && (pl_sd=(struct map_session_data *) session[i]->session_data) && pl_sd->state.auth){
if(m == pl_sd->bl.m && pl_sd->pvp_timer == -1) {
pl_sd->pvp_timer=add_timer(gettick()+200,pc_calc_pvprank_timer,pl_sd->bl.id,0);
pl_sd->pvp_rank=0;
@@ -4820,7 +5051,7 @@ int buildin_pvpoff(struct script_state *st)
return 0;
for(i=0;i<fd_max;i++){ //l”•ªƒ‹[ƒv
- if(session[i] && (pl_sd=session[i]->session_data) && pl_sd->state.auth){
+ if(session[i] && (pl_sd=(struct map_session_data *) session[i]->session_data) && pl_sd->state.auth){
if(m == pl_sd->bl.m) {
clif_pvpset(pl_sd,0,0,2);
if(pl_sd->pvp_timer != -1) {
@@ -4899,7 +5130,7 @@ int buildin_maprespawnguildid_sub(struct block_list *bl,va_list ap)
pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,3); // end addition [Valaris]
}
if(md && flag&4){
- if(md->class < 1285 || md->class > 1288)
+ if(md->class_ < 1285 || md->class_ > 1288)
mob_delete(md);
}
return 0;
@@ -4942,15 +5173,15 @@ int buildin_agitcheck(struct script_state *st)
struct map_session_data *sd;
int cond;
- sd=script_rid2sd(st);
cond=conv_num(st,& (st->stack->stack_data[st->start+2]));
if(cond == 0) {
if (agit_flag==1) push_val(st->stack,C_INT,1);
if (agit_flag==0) push_val(st->stack,C_INT,0);
} else {
- if (agit_flag==1) pc_setreg(sd,add_str("@agit_flag"),1);
- if (agit_flag==0) pc_setreg(sd,add_str("@agit_flag"),0);
+ sd=script_rid2sd(st);
+ if (agit_flag==1) pc_setreg(sd,add_str((unsigned char *) "@agit_flag"),1);
+ if (agit_flag==0) pc_setreg(sd,add_str((unsigned char *) "@agit_flag"),0);
}
return 0;
}
@@ -4974,16 +5205,16 @@ int buildin_getcastlename(struct script_state *st)
for(i=0;i<MAX_GUILDCASTLE;i++){
if( (gc=guild_castle_search(i)) != NULL ){
if(strcmp(mapname,gc->map_name)==0){
- buf=(char *)aCalloc(24,sizeof(char));
+ buf=(char *)aCallocA(24,sizeof(char));
strncpy(buf,gc->castle_name,24);
break;
}
}
}
if(buf)
- push_str(st->stack,C_STR,buf);
+ push_str(st->stack,C_STR,(unsigned char *) buf);
else
- push_str(st->stack,C_CONSTSTR,"");
+ push_str(st->stack,C_CONSTSTR,(unsigned char *) "");
return 0;
}
@@ -5130,9 +5361,9 @@ int buildin_getequipcardcnt(struct script_state *st)
return 0;
}
do{
- if( (sd->status.inventory[i].card[c-1] > 4000) &&
- (sd->status.inventory[i].card[c-1] < 5000)){
-
+ if( (sd->status.inventory[i].card[c-1] > 4000 &&
+ sd->status.inventory[i].card[c-1] < 5000) ||
+ itemdb_type(sd->status.inventory[i].card[c-1]) == 6){ // [Celest]
push_val(st->stack,C_INT,(c));
return 0;
}
@@ -5159,8 +5390,9 @@ int buildin_successremovecards(struct script_state *st)
return 0;
}
do{
- if( (sd->status.inventory[i].card[c-1] > 4000) &&
- (sd->status.inventory[i].card[c-1] < 5000)){
+ if( (sd->status.inventory[i].card[c-1] > 4000 &&
+ sd->status.inventory[i].card[c-1] < 5000) ||
+ itemdb_type(sd->status.inventory[i].card[c-1]) == 6){ // [Celest]
cardflag = 1;
item_tmp.id=0,item_tmp.nameid=sd->status.inventory[i].card[c-1];
@@ -5212,10 +5444,11 @@ int buildin_failedremovecards(struct script_state *st)
return 0;
}
do{
- if(( sd->status.inventory[i].card[c-1] > 4000) &&
- (sd->status.inventory[i].card[c-1] < 5000)){
-
- cardflag = 1;
+ if( (sd->status.inventory[i].card[c-1] > 4000 &&
+ sd->status.inventory[i].card[c-1] < 5000) ||
+ itemdb_type(sd->status.inventory[i].card[c-1]) == 6){ // [Celest]
+
+ cardflag = 1;
if(typefail == 2){ // •‹ï‚̂ݑ¹Ž¸‚È‚çAƒJ[ƒh‚͎󂯎æ‚点‚é
item_tmp.id=0,item_tmp.nameid=sd->status.inventory[i].card[c-1];
@@ -5293,9 +5526,9 @@ int buildin_cmdothernpc(struct script_state *st) // Added by RoVeRT
int buildin_inittimer(struct script_state *st) // Added by RoVeRT
{
// struct npc_data *nd=(struct npc_data*)map_id2bl(st->oid);
-
// nd->lastaction=nd->timer=gettick();
- npc_do_ontimer(st->oid, map_id2sd(st->rid), 1);
+
+ npc_do_ontimer(st->oid, 1);
return 0;
}
@@ -5303,9 +5536,9 @@ int buildin_inittimer(struct script_state *st) // Added by RoVeRT
int buildin_stoptimer(struct script_state *st) // Added by RoVeRT
{
// struct npc_data *nd=(struct npc_data*)map_id2bl(st->oid);
-
// nd->lastaction=nd->timer=-1;
- npc_do_ontimer(st->oid, map_id2sd(st->rid), 0);
+
+ npc_do_ontimer(st->oid, 0);
return 0;
}
@@ -5354,10 +5587,13 @@ int buildin_marriage(struct script_state *st)
int buildin_wedding_effect(struct script_state *st)
{
struct map_session_data *sd=script_rid2sd(st);
+ struct block_list *bl;
- if(sd==NULL)
- return 0;
- clif_wedding_effect(&sd->bl);
+ if(sd==NULL) {
+ bl=map_id2bl(st->oid);
+ } else
+ bl=&sd->bl;
+ clif_wedding_effect(bl);
return 0;
}
int buildin_divorce(struct script_state *st)
@@ -5371,6 +5607,56 @@ int buildin_divorce(struct script_state *st)
return 0;
}
+int buildin_ispartneron(struct script_state *st)
+{
+ struct map_session_data *sd=script_rid2sd(st);
+ struct map_session_data *p_sd=NULL;
+
+ if(sd==NULL || !pc_ismarried(sd) ||
+ ((p_sd=map_nick2sd(map_charid2nick(sd->status.partner_id))) == NULL)) {
+ push_val(st->stack,C_INT,0);
+ return 0;
+ }
+
+ push_val(st->stack,C_INT,1);
+ return 0;
+}
+
+int buildin_getpartnerid(struct script_state *st)
+{
+ struct map_session_data *sd=script_rid2sd(st);
+ if (sd == NULL) {
+ push_val(st->stack,C_INT,0);
+ return 0;
+ }
+
+ push_val(st->stack,C_INT,sd->status.partner_id);
+ return 0;
+}
+
+int buildin_warppartner(struct script_state *st)
+{
+ int x,y;
+ char *str;
+ struct map_session_data *sd=script_rid2sd(st);
+ struct map_session_data *p_sd=NULL;
+
+ if(sd==NULL || !pc_ismarried(sd) ||
+ ((p_sd=map_nick2sd(map_charid2nick(sd->status.partner_id))) == NULL)) {
+ push_val(st->stack,C_INT,0);
+ return 0;
+ }
+
+ str=conv_str(st,& (st->stack->stack_data[st->start+2]));
+ x=conv_num(st,& (st->stack->stack_data[st->start+3]));
+ y=conv_num(st,& (st->stack->stack_data[st->start+4]));
+
+ pc_setpos(p_sd,str,x,y,0);
+
+ push_val(st->stack,C_INT,1);
+ return 0;
+}
+
/*================================================
* Script for Displaying MOB Information [Valaris]
*------------------------------------------------
@@ -5379,35 +5665,48 @@ int buildin_strmobinfo(struct script_state *st)
{
int num=conv_num(st,& (st->stack->stack_data[st->start+2]));
- int class=conv_num(st,& (st->stack->stack_data[st->start+3]));
+ int class_=conv_num(st,& (st->stack->stack_data[st->start+3]));
- if(num<=0 || num>=8 || (class>=0 && class<=1000) || class >2000)
+ if((class_>=0 && class_<=1000) || class_ >2000)
return 0;
- if(num==1) {
- char *buf;
- buf=calloc(24, 1);
- buf=mob_db[class].name;
- push_str(st->stack,C_STR,buf);
- return 0;
- }
- else if(num==2) {
- char *buf;
- buf=calloc(24, 1);
- buf=mob_db[class].jname;
- push_str(st->stack,C_STR,buf);
- return 0;
+ switch (num) {
+ case 1:
+ {
+ char *buf;
+ buf=(char *) aCallocA(24, 1);
+// buf=mob_db[class_].name;
+// for string assignments you would need to go for c++ [Shinomori]
+ strcpy(buf,mob_db[class_].name);
+ push_str(st->stack,C_STR,(unsigned char *) buf);
+ break;
+ }
+ case 2:
+ {
+ char *buf;
+ buf=(char *) aCallocA(24, 1);
+// buf=mob_db[class_].jname;
+// for string assignments you would need to go for c++ [Shinomori]
+ strcpy(buf,mob_db[class_].jname);
+ push_str(st->stack,C_STR,(unsigned char *) buf);
+ break;
+ }
+ case 3:
+ push_val(st->stack,C_INT,mob_db[class_].lv);
+ break;
+ case 4:
+ push_val(st->stack,C_INT,mob_db[class_].max_hp);
+ break;
+ case 5:
+ push_val(st->stack,C_INT,mob_db[class_].max_sp);
+ break;
+ case 6:
+ push_val(st->stack,C_INT,mob_db[class_].base_exp);
+ break;
+ case 7:
+ push_val(st->stack,C_INT,mob_db[class_].job_exp);
+ break;
}
- else if(num==3)
- push_val(st->stack,C_INT,mob_db[class].lv);
- else if(num==4)
- push_val(st->stack,C_INT,mob_db[class].max_hp);
- else if(num==5)
- push_val(st->stack,C_INT,mob_db[class].max_sp);
- else if(num==6)
- push_val(st->stack,C_INT,mob_db[class].base_exp);
- else if(num==7)
- push_val(st->stack,C_INT,mob_db[class].job_exp);
return 0;
}
@@ -5417,20 +5716,20 @@ int buildin_strmobinfo(struct script_state *st)
*/
int buildin_guardian(struct script_state *st)
{
- int class=0,amount=1,x=0,y=0,guardian=0;
+ int class_=0,amount=1,x=0,y=0,guardian=0;
char *str,*map,*event="";
map =conv_str(st,& (st->stack->stack_data[st->start+2]));
x =conv_num(st,& (st->stack->stack_data[st->start+3]));
y =conv_num(st,& (st->stack->stack_data[st->start+4]));
str =conv_str(st,& (st->stack->stack_data[st->start+5]));
- class=conv_num(st,& (st->stack->stack_data[st->start+6]));
+ class_=conv_num(st,& (st->stack->stack_data[st->start+6]));
amount=conv_num(st,& (st->stack->stack_data[st->start+7]));
event=conv_str(st,& (st->stack->stack_data[st->start+8]));
if( st->end>st->start+9 )
guardian=conv_num(st,& (st->stack->stack_data[st->start+9]));
- mob_spawn_guardian(map_id2sd(st->rid),map,x,y,str,class,amount,event,guardian);
+ mob_spawn_guardian(map_id2sd(st->rid),map,x,y,str,class_,amount,event,guardian);
return 0;
}
@@ -5471,10 +5770,10 @@ int buildin_getitemname(struct script_state *st)
i_data = NULL;
i_data = itemdb_search(item_id);
- item_name=(char *)aCalloc(24,sizeof(char));
+ item_name=(char *)aCallocA(24,sizeof(char));
strncpy(item_name,i_data->jname,23);
- push_str(st->stack,C_STR,item_name);
+ push_str(st->stack,C_STR,(unsigned char *) item_name);
return 0;
}
@@ -5485,12 +5784,12 @@ int buildin_getitemname(struct script_state *st)
int buildin_petskillbonus(struct script_state *st)
{
- int type,val,duration,timer;
+ int type,val,duration,timer;
struct pet_data *pd;
- struct map_session_data *sd=script_rid2sd(st);
+ struct map_session_data *sd=script_rid2sd(st);
- if(sd==NULL || sd->pd==NULL)
+ if(sd==NULL || sd->pd==NULL)
return 0;
pd=sd->pd;
@@ -5503,10 +5802,17 @@ int buildin_petskillbonus(struct script_state *st)
duration=conv_num(st,& (st->stack->stack_data[st->start+4]));
timer=conv_num(st,& (st->stack->stack_data[st->start+5]));
- pd->skillbonusduration=-1;
- pd->skillbonustimer=-1;
-
- pet_skill_bonus(sd,pd,type,val,duration,timer,0);
+ // initialise bonuses
+ pd->skillbonustype=type;
+ pd->skillbonusval=val;
+ pd->skillduration=duration*1000;
+ pd->skilltimer=timer*1000;
+
+ if (pd->state.skillbonus == -1)
+ pd->state.skillbonus=0; // waiting state
+
+ // wait for timer to start
+ pd->skillbonustimer=add_timer(gettick()+pd->skilltimer,pet_skill_bonus_timer,sd->bl.id,0);
return 0;
}
@@ -5533,7 +5839,7 @@ int buildin_petloot(struct script_state *st)
if(!max)
return 0;
-
+
pd->loot=1;
pd->lootmax=max;
@@ -5550,20 +5856,20 @@ int buildin_getinventorylist(struct script_state *st)
if(!sd) return 0;
for(i=0;i<MAX_INVENTORY;i++){
if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].amount > 0){
- pc_setreg(sd,add_str("@inventorylist_id")+(j<<24),sd->status.inventory[i].nameid);
- pc_setreg(sd,add_str("@inventorylist_amount")+(j<<24),sd->status.inventory[i].amount);
- pc_setreg(sd,add_str("@inventorylist_equip")+(j<<24),sd->status.inventory[i].equip);
- pc_setreg(sd,add_str("@inventorylist_refine")+(j<<24),sd->status.inventory[i].refine);
- pc_setreg(sd,add_str("@inventorylist_identify")+(j<<24),sd->status.inventory[i].identify);
- pc_setreg(sd,add_str("@inventorylist_attribute")+(j<<24),sd->status.inventory[i].attribute);
- pc_setreg(sd,add_str("@inventorylist_card1")+(j<<24),sd->status.inventory[i].card[0]);
- pc_setreg(sd,add_str("@inventorylist_card2")+(j<<24),sd->status.inventory[i].card[1]);
- pc_setreg(sd,add_str("@inventorylist_card3")+(j<<24),sd->status.inventory[i].card[2]);
- pc_setreg(sd,add_str("@inventorylist_card4")+(j<<24),sd->status.inventory[i].card[3]);
+ pc_setreg(sd,add_str((unsigned char *) "@inventorylist_id")+(j<<24),sd->status.inventory[i].nameid);
+ pc_setreg(sd,add_str((unsigned char *) "@inventorylist_amount")+(j<<24),sd->status.inventory[i].amount);
+ pc_setreg(sd,add_str((unsigned char *) "@inventorylist_equip")+(j<<24),sd->status.inventory[i].equip);
+ pc_setreg(sd,add_str((unsigned char *) "@inventorylist_refine")+(j<<24),sd->status.inventory[i].refine);
+ pc_setreg(sd,add_str((unsigned char *) "@inventorylist_identify")+(j<<24),sd->status.inventory[i].identify);
+ pc_setreg(sd,add_str((unsigned char *) "@inventorylist_attribute")+(j<<24),sd->status.inventory[i].attribute);
+ pc_setreg(sd,add_str((unsigned char *) "@inventorylist_card1")+(j<<24),sd->status.inventory[i].card[0]);
+ pc_setreg(sd,add_str((unsigned char *) "@inventorylist_card2")+(j<<24),sd->status.inventory[i].card[1]);
+ pc_setreg(sd,add_str((unsigned char *) "@inventorylist_card3")+(j<<24),sd->status.inventory[i].card[2]);
+ pc_setreg(sd,add_str((unsigned char *) "@inventorylist_card4")+(j<<24),sd->status.inventory[i].card[3]);
j++;
}
}
- pc_setreg(sd,add_str("@inventorylist_count"),j);
+ pc_setreg(sd,add_str((unsigned char *) "@inventorylist_count"),j);
return 0;
}
@@ -5574,13 +5880,13 @@ int buildin_getskilllist(struct script_state *st)
if(!sd) return 0;
for(i=0;i<MAX_SKILL;i++){
if(sd->status.skill[i].id > 0 && sd->status.skill[i].lv > 0){
- pc_setreg(sd,add_str("@skilllist_id")+(j<<24),sd->status.skill[i].id);
- pc_setreg(sd,add_str("@skilllist_lv")+(j<<24),sd->status.skill[i].lv);
- pc_setreg(sd,add_str("@skilllist_flag")+(j<<24),sd->status.skill[i].flag);
+ pc_setreg(sd,add_str((unsigned char *) "@skilllist_id")+(j<<24),sd->status.skill[i].id);
+ pc_setreg(sd,add_str((unsigned char *)"@skilllist_lv")+(j<<24),sd->status.skill[i].lv);
+ pc_setreg(sd,add_str((unsigned char *)"@skilllist_flag")+(j<<24),sd->status.skill[i].flag);
j++;
}
}
- pc_setreg(sd,add_str("@skilllist_count"),j);
+ pc_setreg(sd,add_str((unsigned char *) "@skilllist_count"),j);
return 0;
}
@@ -5604,14 +5910,14 @@ int buildin_clearitem(struct script_state *st)
*/
int buildin_classchange(struct script_state *st)
{
- int class,type;
+ int _class,type;
struct block_list *bl=map_id2bl(st->oid);
-
+
if(bl==NULL) return 0;
- class=conv_num(st,& (st->stack->stack_data[st->start+2]));
+ _class=conv_num(st,& (st->stack->stack_data[st->start+2]));
type=conv_num(st,& (st->stack->stack_data[st->start+3]));
- clif_class_change(bl,class,type);
+ clif_class_change(bl,_class,type);
return 0;
}
@@ -5655,6 +5961,24 @@ int buildin_soundeffect(struct script_state *st)
}
return 0;
}
+
+int buildin_soundeffectall(struct script_state *st)
+{
+ struct map_session_data *sd=script_rid2sd(st);
+ char *name;
+ int type=0;
+
+ name=conv_str(st,& (st->stack->stack_data[st->start+2]));
+ type=conv_num(st,& (st->stack->stack_data[st->start+3]));
+ if(sd)
+ {
+ if(st->oid)
+ clif_soundeffectall(map_id2bl(st->oid),name,type);
+ else
+ clif_soundeffectall(&sd->bl,name,type);
+ }
+ return 0;
+}
/*==========================================
* pet status recovery [Valaris]
*------------------------------------------
@@ -5663,9 +5987,9 @@ int buildin_petrecovery(struct script_state *st)
{
struct pet_data *pd;
- struct map_session_data *sd=script_rid2sd(st);
+ struct map_session_data *sd=script_rid2sd(st);
- if(sd==NULL || sd->pd==NULL)
+ if(sd==NULL || sd->pd==NULL)
return 0;
pd=sd->pd;
@@ -5689,9 +6013,9 @@ int buildin_petheal(struct script_state *st)
{
struct pet_data *pd;
- struct map_session_data *sd=script_rid2sd(st);
+ struct map_session_data *sd=script_rid2sd(st);
- if(sd==NULL || sd->pd==NULL)
+ if(sd==NULL || sd->pd==NULL)
return 0;
pd=sd->pd;
@@ -5707,7 +6031,7 @@ int buildin_petheal(struct script_state *st)
return 0;
}
-
+
/*==========================================
* pet magnificat [Valaris]
*------------------------------------------
@@ -5715,9 +6039,9 @@ int buildin_petheal(struct script_state *st)
int buildin_petmag(struct script_state *st)
{
struct pet_data *pd;
- struct map_session_data *sd=script_rid2sd(st);
+ struct map_session_data *sd=script_rid2sd(st);
- if(sd==NULL || sd->pd==NULL)
+ if(sd==NULL || sd->pd==NULL)
return 0;
pd=sd->pd;
@@ -5742,9 +6066,9 @@ int buildin_petmag(struct script_state *st)
int buildin_petskillattack(struct script_state *st)
{
struct pet_data *pd;
- struct map_session_data *sd=script_rid2sd(st);
+ struct map_session_data *sd=script_rid2sd(st);
- if(sd==NULL || sd->pd==NULL)
+ if(sd==NULL || sd->pd==NULL)
return 0;
pd=sd->pd;
@@ -5753,7 +6077,7 @@ int buildin_petskillattack(struct script_state *st)
return 0;
pd->skilltype=conv_num(st,& (st->stack->stack_data[st->start+2]));
- pd->skillval=conv_num(st,& (st->stack->stack_data[st->start+3]));
+ pd->skillval=conv_num(st,& (st->stack->stack_data[st->start+3]));
pd->skillduration=conv_num(st,& (st->stack->stack_data[st->start+4]));
pd->skilltimer=conv_num(st,& (st->stack->stack_data[st->start+5]));
@@ -5761,6 +6085,24 @@ int buildin_petskillattack(struct script_state *st)
return 0;
}
+
+/*==========================================
+ * Scripted skill effects [Celest]
+ *------------------------------------------
+ */
+int buildin_skilleffect(struct script_state *st)
+{
+ struct map_session_data *sd;
+
+ int skillid=conv_num(st,& (st->stack->stack_data[st->start+2]));
+ int skilllv=conv_num(st,& (st->stack->stack_data[st->start+3]));
+ sd=script_rid2sd(st);
+
+ clif_skill_nodamage(&sd->bl,&sd->bl,skillid,skilllv,1);
+
+ return 0;
+}
+
/*==========================================
* NPC skill effects [Valaris]
*------------------------------------------
@@ -5768,9 +6110,9 @@ int buildin_petskillattack(struct script_state *st)
int buildin_npcskilleffect(struct script_state *st)
{
struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid);
-
+
int skillid=conv_num(st,& (st->stack->stack_data[st->start+2]));
- int skilllv=conv_num(st,& (st->stack->stack_data[st->start+3]));
+ int skilllv=conv_num(st,& (st->stack->stack_data[st->start+3]));
int x=conv_num(st,& (st->stack->stack_data[st->start+4]));
int y=conv_num(st,& (st->stack->stack_data[st->start+5]));
@@ -5814,15 +6156,15 @@ int buildin_specialeffect2(struct script_state *st)
int buildin_nude(struct script_state *st)
{
- struct map_session_data *sd=script_rid2sd(st);
+ struct map_session_data *sd=script_rid2sd(st);
int i;
if(sd==NULL)
return 0;
-
- for(i=0;i<11;i++)
+
+ for(i=0;i<11;i++)
if(sd->equip_index[i] >= 0)
- pc_unequipitem(sd,sd->equip_index[i],1, BF_NORMAL);
+ pc_unequipitem(sd,sd->equip_index[i],2);
return 0;
}
@@ -5848,6 +6190,221 @@ int buildin_gmcommand(struct script_state *st)
}
/*==========================================
+ * Displays a message for the player only (like system messages like "you got an apple" )
+ *------------------------------------------
+ */
+int buildin_dispbottom(struct script_state *st)
+{
+ struct map_session_data *sd=script_rid2sd(st);
+ char *message;
+ message=conv_str(st,& (st->stack->stack_data[st->start+2]));
+ if(sd)
+ clif_disp_onlyself(sd,message,strlen(message));
+ return 0;
+}
+
+/*==========================================
+ * All The Players Full Recovery
+ (HP/SP full restore and resurrect if need)
+ *------------------------------------------
+ */
+int buildin_recovery(struct script_state *st)
+{
+ int i = 0;
+ for (i = 0; i < fd_max; i++) {
+ if (session[i]){
+ struct map_session_data *sd = (struct map_session_data *) session[i]->session_data;
+ if (sd && sd->state.auth) {
+ sd->status.hp = sd->status.max_hp;
+ sd->status.sp = sd->status.max_sp;
+ clif_updatestatus(sd, SP_HP);
+ clif_updatestatus(sd, SP_SP);
+ if(pc_isdead(sd)){
+ pc_setstand(sd);
+ clif_resurrection(&sd->bl, 1);
+ }
+ clif_displaymessage(sd->fd,"You have been recovered!");
+ }
+ }
+ }
+ return 0;
+}
+/*==========================================
+ * Get your pet info: getpetinfo(n)
+ * n -> 0:pet_id 1:pet_class 2:pet_name
+ 3:friendly 4:hungry
+ *------------------------------------------
+ */
+int buildin_getpetinfo(struct script_state *st)
+{
+ struct map_session_data *sd=script_rid2sd(st);
+ int type=conv_num(st,& (st->stack->stack_data[st->start+2]));
+
+ if(sd && sd->status.pet_id){
+ switch(type){
+ case 0:
+ push_val(st->stack,C_INT,sd->status.pet_id);
+ break;
+ case 1:
+ if(sd->pet.class_)
+ push_val(st->stack,C_INT,sd->pet.class_);
+ else
+ push_val(st->stack,C_INT,0);
+ break;
+ case 2:
+ if(sd->pet.name)
+ push_str(st->stack,C_STR,(unsigned char *) sd->pet.name);
+ else
+ push_val(st->stack,C_INT,0);
+ break;
+ case 3:
+ //if(sd->pet.intimate)
+ push_val(st->stack,C_INT,sd->pet.intimate);
+ break;
+ case 4:
+ //if(sd->pet.hungry)
+ push_val(st->stack,C_INT,sd->pet.hungry);
+ break;
+ default:
+ push_val(st->stack,C_INT,0);
+ break;
+ }
+ }else{
+ push_val(st->stack,C_INT,0);
+ }
+ return 0;
+}
+/*==========================================
+ * Shows wether your inventory(and equips) contain
+ selected card or not.
+ checkequipedcard(4001);
+ *------------------------------------------
+ */
+int buildin_checkequipedcard(struct script_state *st)
+{
+ struct map_session_data *sd=script_rid2sd(st);
+ int n,i,c=0;
+ c=conv_num(st,& (st->stack->stack_data[st->start+2]));
+
+ if(sd){
+ for(i=0;i<MAX_INVENTORY;i++){
+ if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].amount){
+ for(n=0;n<4;n++){
+ if(sd->status.inventory[i].card[n]==c){
+ push_val(st->stack,C_INT,1);
+ return 0;
+ }
+ }
+ }
+ }
+ }
+ push_val(st->stack,C_INT,0);
+ return 0;
+}
+
+int buildin_jump_zero(struct script_state *st) {
+ int sel;
+ sel=conv_num(st,& (st->stack->stack_data[st->start+2]));
+ if(!sel) {
+ int pos;
+ if( st->stack->stack_data[st->start+3].type!=C_POS ){
+ printf("script: jump_zero: not label !\n");
+ st->state=END;
+ return 0;
+ }
+
+ pos=conv_num(st,& (st->stack->stack_data[st->start+3]));
+ st->pos=pos;
+ st->state=GOTO;
+ // printf("script: jump_zero: jumpto : %d\n",pos);
+ } else {
+ // printf("script: jump_zero: fail\n");
+ }
+ return 0;
+}
+
+int buildin_select(struct script_state *st)
+{
+ char *buf;
+ int len,i;
+ struct map_session_data *sd;
+
+ sd=script_rid2sd(st);
+
+ if(sd->state.menu_or_input==0){
+ st->state=RERUNLINE;
+ sd->state.menu_or_input=1;
+ for(i=st->start+2,len=16;i<st->end;i++){
+ conv_str(st,& (st->stack->stack_data[i]));
+ len+=strlen(st->stack->stack_data[i].u.str)+1;
+ }
+ buf=(char *)aCalloc(len+1,sizeof(char));
+ buf[0]=0;
+ for(i=st->start+2,len=0;i<st->end;i++){
+ strcat(buf,st->stack->stack_data[i].u.str);
+ strcat(buf,":");
+ }
+ clif_scriptmenu(script_rid2sd(st),st->oid,buf);
+ aFree(buf);
+ } else if(sd->npc_menu==0xff){ // cansel
+ sd->state.menu_or_input=0;
+ st->state=END;
+ } else {
+ pc_setreg(sd,add_str((unsigned char *) "l15"),sd->npc_menu);
+ pc_setreg(sd,add_str((unsigned char *) "@menu"),sd->npc_menu);
+ sd->state.menu_or_input=0;
+ push_val(st->stack,C_INT,sd->npc_menu);
+ }
+ return 0;
+}
+
+/*==========================================
+ * GetMapMobs
+ returns mob counts on a set map:
+ e.g. GetMapMobs("prontera.gat")
+ use "this" - for player's map
+ *------------------------------------------
+ */
+int buildin_getmapmobs(struct script_state *st)
+{
+ char *str=NULL;
+ int m=-1,bx,by,i;
+ int count=0,c;
+ struct block_list *bl;
+
+ str=conv_str(st,& (st->stack->stack_data[st->start+2]));
+
+ if(strcmp(str,"this")==0){
+ struct map_session_data *sd=script_rid2sd(st);
+ if(sd)
+ m=sd->bl.m;
+ else{
+ push_val(st->stack,C_INT,-1);
+ return 0;
+ }
+ }else
+ m=map_mapname2mapid(str);
+
+ if(m < 0){
+ push_val(st->stack,C_INT,-1);
+ return 0;
+ }
+
+ for(by=0;by<=(map[m].ys-1)/BLOCK_SIZE;by++){
+ for(bx=0;bx<=(map[m].xs-1)/BLOCK_SIZE;bx++){
+ bl = map[m].block_mob[bx+by*map[m].bxs];
+ c = map[m].block_mob_count[bx+by*map[m].bxs];
+ for(i=0;i<c && bl;i++,bl=bl->next){
+ if(bl->x>=0 && bl->x<=map[m].xs-1 && bl->y>=0 && bl->y<=map[m].ys-1)
+ count++;
+ }
+ }
+ }
+ push_val(st->stack,C_INT,count);
+ return 0;
+}
+
+/*==========================================
* movenpc [MouseJstr]
*------------------------------------------
*/
@@ -5896,7 +6453,7 @@ int buildin_message(struct script_state *st)
* area) [Valaris]
*------------------------------------------
*/
-
+
int buildin_npctalk(struct script_state *st)
{
char *str;
@@ -5926,16 +6483,16 @@ int buildin_hasitems(struct script_state *st)
{
int i;
struct map_session_data *sd;
-
+
sd=script_rid2sd(st);
-
+
for(i=0; i<MAX_INVENTORY; i++) {
if(sd->status.inventory[i].amount) {
push_val(st->stack,C_INT,1);
return 0;
}
}
-
+
push_val(st->stack,C_INT,0);
return 0;
@@ -6040,14 +6597,14 @@ int buildin_getsavepoint(struct script_state *st)
sd=script_rid2sd(st);
type=conv_num(st,& (st->stack->stack_data[st->start+2]));
- mapname=calloc(24, 1);
+ mapname=(char *) aCallocA(24, 1);
x=sd->status.save_point.x;
y=sd->status.save_point.y;
strncpy(mapname,sd->status.save_point.map,24);
switch(type){
case 0:
- push_str(st->stack,C_STR,mapname);
+ push_str(st->stack,C_STR,(unsigned char *) mapname);
break;
case 1:
push_val(st->stack,C_INT,x);
@@ -6109,7 +6666,7 @@ int buildin_getmapxy(struct script_state *st){
//??????????? >>> Possible needly check function parameters on C_STR,C_INT,C_INT <<< ???????????//
type=conv_num(st,& (st->stack->stack_data[st->start+5]));
- mapname=calloc(24, 1);
+ mapname=(char *) aCallocA(24, 1);
switch (type){
case 0: //Get Character Position
@@ -6141,7 +6698,7 @@ int buildin_getmapxy(struct script_state *st){
}
x=nd->bl.x;
- y=nd->bl.y;
+ y=nd->bl.y;
strncpy(mapname,map[nd->bl.m].name,24);
printf(">>>>%s %d %d\n",mapname,x,y);
break;
@@ -6163,7 +6720,7 @@ int buildin_getmapxy(struct script_state *st){
return 0;
}
x=pd->bl.x;
- y=pd->bl.y;
+ y=pd->bl.y;
strncpy(mapname,map[pd->bl.m].name,24);
printf(">>>>%s %d %d\n",mapname,x,y);
@@ -6218,6 +6775,260 @@ int buildin_getmapxy(struct script_state *st){
return 0;
}
+/*=====================================================
+ * Allows players to use a skill - by Qamera
+ *-----------------------------------------------------
+ */
+int buildin_skilluseid (struct script_state *st)
+{
+ int skid,sklv;
+ struct map_session_data *sd;
+
+ skid=conv_num(st,& (st->stack->stack_data[st->start+2]));
+ sklv=conv_num(st,& (st->stack->stack_data[st->start+3]));
+ sd=script_rid2sd(st);
+ skill_use_id(sd,sd->status.account_id,skid,sklv);
+
+ return 0;
+}
+
+/*=====================================================
+ * Allows players to use a skill on a position [Celest]
+ *-----------------------------------------------------
+ */
+int buildin_skillusepos(struct script_state *st)
+{
+ int skid,sklv,x,y;
+ struct map_session_data *sd;
+
+ skid=conv_num(st,& (st->stack->stack_data[st->start+2]));
+ sklv=conv_num(st,& (st->stack->stack_data[st->start+3]));
+ x=conv_num(st,& (st->stack->stack_data[st->start+4]));
+ y=conv_num(st,& (st->stack->stack_data[st->start+5]));
+
+ sd=script_rid2sd(st);
+ skill_use_pos(sd,x,y,skid,sklv);
+
+ return 0;
+}
+
+/*==========================================
+ * Allows player to write NPC logs (i.e. Bank NPC, etc) [Lupus]
+ *------------------------------------------
+ */
+int buildin_logmes(struct script_state *st)
+{
+ if (log_config.npc <= 0 ) return 0;
+ conv_str(st,& (st->stack->stack_data[st->start+2]));
+ log_npc(script_rid2sd(st),st->stack->stack_data[st->start+2].u.str);
+ return 0;
+}
+
+int buildin_summon(struct script_state *st)
+{
+ int _class, id;
+ char *str,*event="";
+ struct map_session_data *sd;
+ struct mob_data *md;
+
+ sd=script_rid2sd(st);
+ if (sd) {
+ int tick = gettick();
+ str =conv_str(st,& (st->stack->stack_data[st->start+2]));
+ _class=conv_num(st,& (st->stack->stack_data[st->start+3]));
+ if( st->end>st->start+4 )
+ event=conv_str(st,& (st->stack->stack_data[st->start+4]));
+
+ id=mob_once_spawn(sd, "this", 0, 0, str,_class,1,event);
+ if((md=(struct mob_data *)map_id2bl(id))){
+ md->master_id=sd->bl.id;
+ md->state.special_mob_ai=1;
+ md->mode=mob_db[md->class_].mode|0x04;
+ md->deletetimer=add_timer(tick+60000,mob_timer_delete,id,0);
+ clif_misceffect2(&md->bl,344);
+ }
+ clif_skill_poseffect(&sd->bl,AM_CALLHOMUN,1,sd->bl.x,sd->bl.y,tick);
+ }
+
+ return 0;
+}
+
+int buildin_isnight(struct script_state *st)
+{
+ push_val(st->stack,C_INT, (night_flag == 1));
+ return 0;
+}
+
+int buildin_isday(struct script_state *st)
+{
+ push_val(st->stack,C_INT, (night_flag == 0));
+ return 0;
+}
+
+/*================================================
+ * Check whether another item/card has been
+ * equipped - used for 2/15's cards patch [celest]
+ *------------------------------------------------
+ */
+int buildin_isequipped(struct script_state *st)
+{
+ struct map_session_data *sd;
+ int i, j, k, id = 1;
+ int ret = -1;
+
+ sd = script_rid2sd(st);
+
+ for (i=0; id!=0; i++) {
+ int flag = 0;
+
+ FETCH (i+2, id) else id = 0;
+ if (id <= 0)
+ continue;
+
+ for (j=0; j<10; j++) {
+ int index, type;
+ index = sd->equip_index[j];
+ if(index < 0) continue;
+ if(j == 9 && sd->equip_index[8] == index) continue;
+ if(j == 5 && sd->equip_index[4] == index) continue;
+ if(j == 6 && (sd->equip_index[5] == index || sd->equip_index[4] == index)) continue;
+ type = itemdb_type(id);
+
+ if(sd->inventory_data[index]) {
+ if (type == 4 || type == 5) {
+ if (sd->inventory_data[index]->nameid == id)
+ flag = 1;
+ } else if (type == 6) {
+ for(k=0; k<sd->inventory_data[index]->slot; k++) {
+ if (sd->status.inventory[index].card[0]!=0x00ff &&
+ sd->status.inventory[index].card[0]!=0x00fe &&
+ sd->status.inventory[index].card[0]!=(short)0xff00 &&
+ sd->status.inventory[index].card[k] == id) {
+ flag = 1;
+ break;
+ }
+ }
+ }
+ if (flag) break;
+ }
+ }
+ if (ret == -1)
+ ret = flag;
+ else
+ ret &= flag;
+ if (!ret) break;
+ }
+
+ push_val(st->stack,C_INT,ret);
+ return 0;
+}
+
+/*================================================
+ * Check how many items/cards in the list are
+ * equipped - used for 2/15's cards patch [celest]
+ *------------------------------------------------
+ */
+int buildin_isequippedcnt(struct script_state *st)
+{
+ struct map_session_data *sd;
+ int i, j, k, id = 1;
+ int ret = 0;
+
+ sd = script_rid2sd(st);
+
+ for (i=0; id!=0; i++) {
+ FETCH (i+2, id) else id = 0;
+ if (id <= 0)
+ continue;
+
+ for (j=0; j<10; j++) {
+ int index, type;
+ index = sd->equip_index[j];
+ if(index < 0) continue;
+ if(j == 9 && sd->equip_index[8] == index) continue;
+ if(j == 5 && sd->equip_index[4] == index) continue;
+ if(j == 6 && (sd->equip_index[5] == index || sd->equip_index[4] == index)) continue;
+ type = itemdb_type(id);
+
+ if(sd->inventory_data[index]) {
+ if (type == 4 || type == 5) {
+ if (sd->inventory_data[index]->nameid == id)
+ ret++; //[Lupus]
+ } else if (type == 6) {
+ for(k=0; k<sd->inventory_data[index]->slot; k++) {
+ if (sd->status.inventory[index].card[0]!=0x00ff &&
+ sd->status.inventory[index].card[0]!=0x00fe &&
+ sd->status.inventory[index].card[0]!=(short)0xff00 &&
+ sd->status.inventory[index].card[k] == id) {
+ ret++; //[Lupus]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ push_val(st->stack,C_INT,ret);
+ return 0;
+}
+
+/*================================================
+ * Check how many given inserted cards in the CURRENT
+ * weapon - used for 2/15's cards patch [Lupus]
+ *------------------------------------------------
+ */
+int buildin_cardscnt(struct script_state *st)
+{
+ struct map_session_data *sd;
+ int i, k, id = 1;
+ int ret = 0;
+ int index, type;
+
+ sd = script_rid2sd(st);
+
+ for (i=0; id!=0; i++) {
+ FETCH (i+2, id) else id = 0;
+ if (id <= 0)
+ continue;
+
+ index = current_equip_item_index; //we get CURRENT WEAPON inventory index from status.c [Lupus]
+ if(index < 0) continue;
+
+ type = itemdb_type(id);
+
+ if(sd->inventory_data[index]) {
+ if (type == 4 || type == 5) {
+ if (sd->inventory_data[index]->nameid == id)
+ ret++;
+ } else if (type == 6) {
+ for(k=0; k<sd->inventory_data[index]->slot; k++) {
+ if (sd->status.inventory[index].card[0]!=0x00ff &&
+ sd->status.inventory[index].card[0]!=0x00fe &&
+ sd->status.inventory[index].card[0]!=(short)0xff00 &&
+ sd->status.inventory[index].card[k] == id) {
+ ret++;
+ }
+ }
+ }
+ }
+ }
+ push_val(st->stack,C_INT,ret);
+// push_val(st->stack,C_INT,current_equip_item_index);
+ return 0;
+}
+
+/*=======================================================
+ * Returns the refined number of the current item, or an
+ * item with inventory index specified
+ *-------------------------------------------------------
+ */
+int buildin_getrefine(struct script_state *st)
+{
+ struct map_session_data *sd;
+ if ((sd = script_rid2sd(st))!= NULL)
+ push_val(st->stack, C_INT, sd->status.inventory[current_equip_item_index].refine);
+ return 0;
+}
//
// ŽÀs•”main
@@ -6309,14 +7120,14 @@ void op_add(struct script_state* st)
st->stack->stack_data[st->stack->sp-1].u.num += st->stack->stack_data[st->stack->sp].u.num;
} else { // ss‚Ì—\’è
char *buf;
- buf=(char *)aCalloc(strlen(st->stack->stack_data[st->stack->sp-1].u.str)+
+ buf=(char *)aCallocA(strlen(st->stack->stack_data[st->stack->sp-1].u.str)+
strlen(st->stack->stack_data[st->stack->sp].u.str)+1,sizeof(char));
strcpy(buf,st->stack->stack_data[st->stack->sp-1].u.str);
strcat(buf,st->stack->stack_data[st->stack->sp].u.str);
if(st->stack->stack_data[st->stack->sp-1].type==C_STR)
- free(st->stack->stack_data[st->stack->sp-1].u.str);
+ aFree(st->stack->stack_data[st->stack->sp-1].u.str);
if(st->stack->stack_data[st->stack->sp].type==C_STR)
- free(st->stack->stack_data[st->stack->sp].u.str);
+ aFree(st->stack->stack_data[st->stack->sp].u.str);
st->stack->stack_data[st->stack->sp-1].type=C_STR;
st->stack->stack_data[st->stack->sp-1].u.str=buf;
}
@@ -6358,8 +7169,8 @@ void op_2str(struct script_state *st,int op,int sp1,int sp2)
push_val(st->stack,C_INT,a);
- if(st->stack->stack_data[sp1].type==C_STR) free(s1);
- if(st->stack->stack_data[sp2].type==C_STR) free(s2);
+ if(st->stack->stack_data[sp1].type==C_STR) aFree(s1);
+ if(st->stack->stack_data[sp2].type==C_STR) aFree(s2);
}
/*==========================================
* “ñ€‰‰ŽZŽq(”’l)
@@ -6373,7 +7184,11 @@ void op_2num(struct script_state *st,int op,int i1,int i2)
break;
case C_MUL:
{
+ #ifndef _MSC_VER
long long res = i1 * i2;
+ #else
+ __int64 res = i1 * i2;
+ #endif
if (res > 2147483647 )
i1 = 2147483647;
else
@@ -6572,7 +7387,7 @@ int run_func(struct script_state *st)
* ƒXƒNƒŠƒvƒg‚ÌŽÀsƒƒCƒ“•”•ª
*------------------------------------------
*/
-int run_script_main(unsigned char *script,int pos,int rid,int oid,struct script_state *st,unsigned char *rootscript)
+int run_script_main(char *script,int pos,int rid,int oid,struct script_state *st,char *rootscript)
{
int c,rerun_pos;
int cmdcount=script_config.check_cmdcount;
@@ -6584,7 +7399,7 @@ int run_script_main(unsigned char *script,int pos,int rid,int oid,struct script_
rerun_pos=st->pos;
for(st->state=0;st->state==0;){
- switch(c=get_com(script,&st->pos)){
+ switch(c= get_com((unsigned char *) script,&st->pos)){
case C_EOL:
if(stack->sp!=st->defsp){
if(battle_config.error_log)
@@ -6594,7 +7409,7 @@ int run_script_main(unsigned char *script,int pos,int rid,int oid,struct script_
rerun_pos=st->pos;
break;
case C_INT:
- push_val(stack,C_INT,get_num(script,&st->pos));
+ push_val(stack,C_INT,get_num((unsigned char *) script,&st->pos));
break;
case C_POS:
case C_NAME:
@@ -6605,7 +7420,7 @@ int run_script_main(unsigned char *script,int pos,int rid,int oid,struct script_
push_val(stack,c,0);
break;
case C_STR:
- push_str(stack,C_CONSTSTR,script+st->pos);
+ push_str(stack,C_CONSTSTR,(unsigned char *) (script+st->pos));
while(script[st->pos++]);
break;
case C_FUNC:
@@ -6689,7 +7504,7 @@ int run_script_main(unsigned char *script,int pos,int rid,int oid,struct script_
struct map_session_data *sd=map_id2sd(st->rid);
if(sd/* && sd->npc_stackbuf==NULL*/){
if( sd->npc_stackbuf )
- free( sd->npc_stackbuf );
+ aFree( sd->npc_stackbuf );
sd->npc_stackbuf = (char *)aCalloc(sizeof(stack->stack_data[0])*stack->sp_max,sizeof(char));
memcpy(sd->npc_stackbuf, stack->stack_data, sizeof(stack->stack_data[0]) * stack->sp_max);
sd->npc_stack = stack->sp;
@@ -6706,24 +7521,24 @@ int run_script_main(unsigned char *script,int pos,int rid,int oid,struct script_
* ƒXƒNƒŠƒvƒg‚ÌŽÀs
*------------------------------------------
*/
-int run_script(unsigned char *script,int pos,int rid,int oid)
+int run_script(char *script,int pos,int rid,int oid)
{
struct script_stack stack;
struct script_state st;
struct map_session_data *sd=map_id2sd(rid);
- unsigned char *rootscript=script;
+ char *rootscript=script;
if(script==NULL || pos<0)
return -1;
- if(sd && sd->npc_stackbuf && sd->npc_scriptroot==(char*)rootscript){
+ if(sd && sd->npc_stackbuf && sd->npc_scriptroot==rootscript){
// ‘O‰ñ‚̃Xƒ^ƒbƒN‚𕜋A
script=sd->npc_script;
stack.sp=sd->npc_stack;
stack.sp_max=sd->npc_stackmax;
stack.stack_data=(struct script_data *)aCalloc(stack.sp_max,sizeof(stack.stack_data[0]));
memcpy(stack.stack_data,sd->npc_stackbuf,sizeof(stack.stack_data[0])*stack.sp_max);
- free(sd->npc_stackbuf);
+ aFree(sd->npc_stackbuf);
sd->npc_stackbuf=NULL;
}else{
// ƒXƒ^ƒbƒN‰Šú‰»
@@ -6737,7 +7552,7 @@ int run_script(unsigned char *script,int pos,int rid,int oid)
st.oid=oid;
run_script_main(script,pos,rid,oid,&st,rootscript);
- free(stack.stack_data);
+ aFree(stack.stack_data);
stack.stack_data=NULL;
return st.pos;
}
@@ -6765,15 +7580,15 @@ int mapreg_setregstr(int num,const char *str)
{
char *p;
- if( (p=numdb_search(mapregstr_db,num))!=NULL )
- free(p);
+ if( (p=(char *) numdb_search(mapregstr_db,num))!=NULL )
+ aFree(p);
if( str==NULL || *str==0 ){
numdb_erase(mapregstr_db,num);
mapreg_dirty=1;
return 0;
}
- p=(char *)aCalloc(strlen(str)+1, sizeof(char));
+ p=(char *)aCallocA(strlen(str)+1, sizeof(char));
strcpy(p,str);
numdb_insert(mapregstr_db,num,p);
mapreg_dirty=1;
@@ -6803,16 +7618,16 @@ static int script_load_mapreg()
printf("%s: %s broken data !\n",mapreg_txt,buf1);
continue;
}
- p=(char *)aCalloc(strlen(buf2) + 1,sizeof(char));
+ p=(char *)aCallocA(strlen(buf2) + 1,sizeof(char));
strcpy(p,buf2);
- s=add_str(buf1);
+ s= add_str((unsigned char *) buf1);
numdb_insert(mapregstr_db,(i<<24)|s,p);
}else{
if( sscanf(line+n,"%d",&v)!=1 ){
printf("%s: %s broken data !\n",mapreg_txt,buf1);
continue;
}
- s=add_str(buf1);
+ s= add_str((unsigned char *) buf1);
numdb_insert(mapreg_db,(i<<24)|s,v);
}
}
@@ -6871,7 +7686,7 @@ static int script_autosave_mapreg(int tid,unsigned int tick,int id,int data)
}
/*==========================================
- *
+ *
*------------------------------------------
*/
static int set_posword(char *p)
@@ -6903,8 +7718,16 @@ int script_config_read(char *cfgName)
script_config.warn_cmd_no_comma=1;
script_config.warn_func_mismatch_paramnum=1;
script_config.warn_cmd_mismatch_paramnum=1;
- script_config.check_cmdcount=8192;
- script_config.check_gotocount=512;
+ script_config.check_cmdcount=65535;
+ script_config.check_gotocount=2048;
+
+ script_config.die_event_name = (char *)aCallocA(24,sizeof(char));
+ script_config.kill_event_name = (char *)aCallocA(24,sizeof(char));
+ script_config.login_event_name = (char *)aCallocA(24,sizeof(char));
+ script_config.logout_event_name = (char *)aCallocA(24,sizeof(char));
+
+ script_config.event_script_type = 0;
+ script_config.event_requires_trigger = 1;
fp=fopen(cfgName,"r");
if(fp==NULL){
@@ -6920,7 +7743,43 @@ int script_config_read(char *cfgName)
if(strcmpi(w1,"refine_posword")==0) {
set_posword(w2);
}
- if(strcmpi(w1,"import")==0){
+ else if(strcmpi(w1,"warn_func_no_comma")==0) {
+ script_config.warn_func_no_comma = battle_config_switch(w2);
+ }
+ else if(strcmpi(w1,"warn_cmd_no_comma")==0) {
+ script_config.warn_cmd_no_comma = battle_config_switch(w2);
+ }
+ else if(strcmpi(w1,"warn_func_mismatch_paramnum")==0) {
+ script_config.warn_func_mismatch_paramnum = battle_config_switch(w2);
+ }
+ else if(strcmpi(w1,"warn_cmd_mismatch_paramnum")==0) {
+ script_config.warn_cmd_mismatch_paramnum = battle_config_switch(w2);
+ }
+ else if(strcmpi(w1,"check_cmdcount")==0) {
+ script_config.check_cmdcount = battle_config_switch(w2);
+ }
+ else if(strcmpi(w1,"check_gotocount")==0) {
+ script_config.check_gotocount = battle_config_switch(w2);
+ }
+ else if(strcmpi(w1,"event_script_type")==0) {
+ script_config.event_script_type = battle_config_switch(w2);
+ }
+ else if(strcmpi(w1,"die_event_name")==0) {
+ strcpy(script_config.die_event_name, w2);
+ }
+ else if(strcmpi(w1,"kill_event_name")==0) {
+ strcpy(script_config.kill_event_name, w2);
+ }
+ else if(strcmpi(w1,"login_event_name")==0) {
+ strcpy(script_config.login_event_name, w2);
+ }
+ else if(strcmpi(w1,"logout_event_name")==0) {
+ strcpy(script_config.logout_event_name, w2);
+ }
+ else if(strcmpi(w1,"require_set_trigger")==0) {
+ script_config.event_requires_trigger = battle_config_switch(w2);
+ }
+ else if(strcmpi(w1,"import")==0){
script_config_read(w2);
}
}
@@ -6939,7 +7798,7 @@ static int mapreg_db_final(void *key,void *data,va_list ap)
}
static int mapregstr_db_final(void *key,void *data,va_list ap)
{
- free(data);
+ aFree(data);
return 0;
}
static int scriptlabel_db_final(void *key,void *data,va_list ap)
@@ -6948,16 +7807,16 @@ static int scriptlabel_db_final(void *key,void *data,va_list ap)
}
static int userfunc_db_final(void *key,void *data,va_list ap)
{
- free(key);
- free(data);
+ aFree(key);
+ aFree(data);
return 0;
}
int do_final_script()
{
if(mapreg_dirty>=0)
script_save_mapreg();
- if(script_buf)
- free(script_buf);
+// if(script_buf)
+// aFree(script_buf);
if(mapreg_db)
numdb_final(mapreg_db,mapreg_db_final);
@@ -6968,10 +7827,19 @@ int do_final_script()
if(userfunc_db)
strdb_final(userfunc_db,userfunc_db_final);
- if (str_data)
- free(str_data);
- if (str_buf)
- free(str_buf);
+ if (str_data)
+ aFree(str_data);
+ if (str_buf)
+ aFree(str_buf);
+
+ if (script_config.die_event_name)
+ aFree(script_config.die_event_name);
+ if (script_config.kill_event_name)
+ aFree(script_config.kill_event_name);
+ if (script_config.login_event_name)
+ aFree(script_config.login_event_name);
+ if (script_config.logout_event_name)
+ aFree(script_config.logout_event_name);
return 0;
}
diff --git a/src/map/script.h b/src/map/script.h
index b50c46693..b30201a67 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -2,6 +2,22 @@
#ifndef _SCRIPT_H_
#define _SCRIPT_H_
+extern struct Script_Config {
+ int warn_func_no_comma;
+ int warn_cmd_no_comma;
+ int warn_func_mismatch_paramnum;
+ int warn_cmd_mismatch_paramnum;
+ int check_cmdcount;
+ int check_gotocount;
+
+ int event_script_type;
+ char* die_event_name;
+ char* kill_event_name;
+ char* login_event_name;
+ char* logout_event_name;
+ int event_requires_trigger;
+} script_config;
+
struct script_data {
int type;
union {
@@ -23,8 +39,12 @@ struct script_state {
int defsp,new_pos,new_defsp;
};
-unsigned char * parse_script(unsigned char *,int);
-int run_script(unsigned char *,int,int,int);
+char * parse_script(unsigned char *,int);
+int run_script(char *,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);
+char* conv_str(struct script_state *st,struct script_data *data);
struct dbt* script_get_label_db();
struct dbt* script_get_userfunc_db();
diff --git a/src/map/skill.c b/src/map/skill.c
index dc708c906..c53a7a9d6 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -1,4 +1,4 @@
-// $Id: skill.c,v 1.8 2004/11/26 7:12:23 PM Celestia Exp $
+// $Id: skill.c,v 1.8 2004/02/27 5:34:51 PM Celestia $
/* ƒXƒLƒ‹?ŒW */
#include <stdio.h>
@@ -14,6 +14,7 @@
#include "map.h"
#include "clif.h"
#include "pc.h"
+#include "status.h"
#include "pet.h"
#include "mob.h"
#include "battle.h"
@@ -24,245 +25,16 @@
#include "log.h"
#include "chrif.h"
#include "guild.h"
+#include "showmsg.h"
+#include "grfio.h"
#ifdef MEMWATCH
#include "memwatch.h"
#endif
#define SKILLUNITTIMER_INVERVAL 100
-
#define STATE_BLIND 0x10
-
-/* ƒXƒLƒ‹”Ô?„ƒXƒe?ƒ^ƒXˆÙí”Ô??Š·ƒe?ƒuƒ‹ */
-int SkillStatusChangeTable[]={ /* skill.h‚Ìenum‚ÌSC_***‚Æ‚ ‚킹‚邱‚Æ */
-/* 0- */
- -1,-1,-1,-1,-1,-1,
- SC_PROVOKE, /* ƒvƒƒ{ƒbƒN */
- -1, 1,-1,
-/* 10- */
- SC_SIGHT, /* ƒTƒCƒg */
- -1,-1,-1,-1,
- SC_FREEZE, /* ƒtƒƒXƒgƒ_ƒCƒo? */
- SC_STONE, /* ƒXƒg?ƒ“ƒJ?ƒX */
- -1,-1,-1,
-/* 20- */
- -1,-1,-1,-1,
- SC_RUWACH, /* ƒ‹ƒAƒt */
- -1,-1,-1,-1,
- SC_INCREASEAGI, /* ‘¬“x?‰Á */
-/* 30- */
- SC_DECREASEAGI, /* ‘¬“xŒ¸­ */
- -1,
- SC_SIGNUMCRUCIS, /* ƒVƒOƒiƒ€ƒNƒ‹ƒVƒX */
- SC_ANGELUS, /* ƒGƒ“ƒWƒFƒ‰ƒX */
- SC_BLESSING, /* ƒuƒŒƒbƒVƒ“ƒO */
- -1,-1,-1,-1,-1,
-/* 40- */
- -1,-1,-1,-1,-1,
- SC_CONCENTRATE, /* W’†—ÍŒüã */
- -1,-1,-1,-1,
-/* 50- */
- -1,
- SC_HIDING, /* ƒnƒCƒfƒBƒ“ƒO */
- -1,-1,-1,-1,-1,-1,-1,-1,
-/* 60- */
- SC_TWOHANDQUICKEN, /* 2HQ */
- SC_AUTOCOUNTER,
- -1,-1,-1,-1,
- SC_IMPOSITIO, /* ƒCƒ“ƒ|ƒVƒeƒBƒIƒ}ƒkƒX */
- SC_SUFFRAGIUM, /* ƒTƒtƒ‰ƒMƒEƒ€ */
- SC_ASPERSIO, /* ƒAƒXƒyƒ‹ƒVƒI */
- SC_BENEDICTIO, /* ¹?~•Ÿ */
-/* 70- */
- -1,
- SC_SLOWPOISON,
- -1,
- SC_KYRIE, /* ƒLƒŠƒGƒGƒŒƒCƒ\ƒ“ */
- SC_MAGNIFICAT, /* ƒ}ƒOƒjƒtƒBƒJ?ƒg */
- SC_GLORIA, /* ƒOƒƒŠƒA */
- SC_DIVINA, /* ƒŒƒbƒNƒXƒfƒBƒr?ƒi */
- -1,
- SC_AETERNA, /* ƒŒƒbƒNƒXƒG?ƒeƒ‹ƒi */
- -1,
-/* 80- */
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-/* 90- */
- -1,-1,
- SC_QUAGMIRE, /* ƒNƒ@ƒOƒ}ƒCƒA */
- -1,-1,-1,-1,-1,-1,-1,
-/* 100- */
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-/* 110- */
- -1,
- SC_ADRENALINE, /* ƒAƒhƒŒƒiƒŠƒ“ƒ‰ƒbƒVƒ… */
- SC_WEAPONPERFECTION,/* ƒEƒFƒ|ƒ“ƒp?ƒtƒFƒNƒVƒ‡ƒ“ */
- SC_OVERTHRUST, /* ƒI?ƒo?ƒgƒ‰ƒXƒg */
- SC_MAXIMIZEPOWER, /* ƒ}ƒLƒVƒ}ƒCƒYƒpƒ? */
- -1,-1,-1,-1,-1,
-/* 120- */
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-/* 130- */
- -1,-1,-1,-1,-1,
- SC_CLOAKING, /* ƒNƒ?ƒLƒ“ƒO */
- SC_STAN, /* ƒ\ƒjƒbƒNƒuƒ? */
- -1,
- SC_ENCPOISON, /* ƒGƒ“ƒ`ƒƒƒ“ƒgƒ|ƒCƒYƒ“ */
- SC_POISONREACT, /* ƒ|ƒCƒYƒ“ƒŠƒAƒNƒg */
-/* 140- */
- SC_POISON, /* ƒxƒmƒ€ƒ_ƒXƒg */
- SC_SPLASHER, /* ƒxƒiƒ€ƒXƒvƒ‰ƒbƒVƒƒ? */
- -1,
- SC_TRICKDEAD, /* Ž€‚ñ‚¾‚Ó‚è */
- -1,-1,-1,-1,-1,-1,
-/* 150- */
- -1,-1,-1,-1,-1,
- SC_LOUD, /* ƒ‰ƒEƒhƒ{ƒCƒX */
- -1,
- SC_ENERGYCOAT, /* ƒGƒiƒW?ƒR?ƒg */
- -1,-1,
-/* 160- */
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,
- SC_SELFDESTRUCTION,
- -1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,
- SC_KEEPING,
- -1,-1,
- SC_BARRIER,
- -1,-1,
- SC_HALLUCINATION,
- -1,-1,
-/* 210- */
- -1,-1,-1,-1,-1,
- SC_STRIPWEAPON,
- SC_STRIPSHIELD,
- SC_STRIPARMOR,
- SC_STRIPHELM,
- -1,
-/* 220- */
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-/* 230- */
- -1,-1,-1,-1,
- SC_CP_WEAPON,
- SC_CP_SHIELD,
- SC_CP_ARMOR,
- SC_CP_HELM,
- -1,-1,
-/* 240- */
- -1,-1,-1,-1,-1,-1,-1,-1,-1,
- SC_AUTOGUARD,
-/* 250- */
- -1,-1,
- SC_REFLECTSHIELD,
- -1,-1,
- SC_DEVOTION,
- SC_PROVIDENCE,
- SC_DEFENDER,
- SC_SPEARSQUICKEN,
- -1,
-/* 260- */
- -1,-1,-1,-1,-1,-1,-1,-1,
- SC_STEELBODY,
- SC_BLADESTOP_WAIT,
-/* 270- */
- SC_EXPLOSIONSPIRITS,
- SC_EXTREMITYFIST,
- -1,-1,-1,-1,
- SC_MAGICROD,
- -1,-1,-1,
-/* 280- */
- SC_FLAMELAUNCHER,
- SC_FROSTWEAPON,
- SC_LIGHTNINGLOADER,
- SC_SEISMICWEAPON,
- -1,
- SC_VOLCANO,
- SC_DELUGE,
- SC_VIOLENTGALE,
- SC_LANDPROTECTOR,
- -1,
-/* 290- */
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-/* 300- */
- -1,-1,-1,-1,-1,-1,
- SC_LULLABY,
- SC_RICHMANKIM,
- SC_ETERNALCHAOS,
- SC_DRUMBATTLE,
-/* 310- */
- SC_NIBELUNGEN,
- SC_ROKISWEIL,
- SC_INTOABYSS,
- SC_SIEGFRIED,
- -1,-1,-1,
- SC_DISSONANCE,
- -1,
- SC_WHISTLE,
-/* 320- */
- SC_ASSNCROS,
- SC_POEMBRAGI,
- SC_APPLEIDUN,
- -1,-1,
- SC_UGLYDANCE,
- -1,
- SC_HUMMING,
- SC_DONTFORGETME,
- SC_FORTUNE,
-/* 330- */
- SC_SERVICE4U,
- SC_SELFDESTRUCTION,
- -1,-1,-1,-1,-1,-1,-1,-1,
-/* 340- */
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-/* 350- */
- -1,-1,-1,-1,-1,
- SC_AURABLADE,
- SC_PARRYING,
- SC_CONCENTRATION,
- SC_TENSIONRELAX,
- SC_BERSERK,
-/* 360- */
- SC_BERSERK,
- SC_ASSUMPTIO,
- SC_BASILICA,
- -1,-1,-1,
- SC_MAGICPOWER,
- -1,-1,
- SC_GOSPEL,
-/* 370- */
- -1,-1,-1,-1,-1,-1,-1,-1,
-
- SC_EDP,
-
- -1,
-/* 380- */
- SC_TRUESIGHT,
- -1,-1,
- SC_WINDWALK,
- SC_MELTDOWN,
- -1,-1,
- SC_CARTBOOST,
- -1,
- SC_CHASEWALK,
-/* 390- */
- SC_REJECTSWORD,
- -1,-1,-1,-1,-1,
- SC_MARIONETTE,
- -1,
- SC_HEADCRUSH,
- SC_JOINTBEAT,
-/* 400 */
- -1,-1,
- SC_MINDBREAKER,
- SC_MEMORIZE,
- SC_FOGWALL,
- SC_SPIDERWEB,
- -1,-1,-1,-1,
-/* 410- */
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-};
+#define swap(x,y) { int t; t = x; x = y; y = t; }
const struct skill_name_db skill_names[] = {
{ AC_CHARGEARROW, "CHARGEARROW", "Charge_Arrow" } ,
@@ -398,6 +170,10 @@ const struct skill_name_db skill_names[] = {
{ DC_SERVICEFORYOU, "SERVICEFORYOU", "Prostitute" } ,
{ DC_THROWARROW, "THROWARROW", "Throw_Arrow" } ,
{ DC_UGLYDANCE, "UGLYDANCE", "Ugly_Dance" } ,
+ { GD_BATTLEORDER, "BATTLEORDER", "Battle_Orders" } ,
+ { GD_REGENERATION, "REGENERATION", "Regeneration" } ,
+ { GD_RESTORE, "RESTORE", "Restore" } ,
+ { GD_EMERGENCYCALL, "EMERGENCYCALL", "Emergency_Call" } ,
{ HP_ASSUMPTIO, "ASSUMPTIO", "Assumptio" } ,
{ HP_BASILICA, "BASILICA", "Basilica" } ,
{ HP_MEDITATIO, "MEDITATIO", "Meditation" } ,
@@ -698,9 +474,9 @@ const struct skill_name_db skill_names[] = {
{ TK_SPTIME, "SPTIME", "SP Time" } ,
{ TK_STORMKICK, "STORMKICK", "Storm Kick" } ,
{ TK_TURNKICK, "TURNKICK", "Turn Kick" } ,
- { WE_BABY, "BABY", "Adopt_Baby" } ,
- { WE_CALLBABY, "CALLBABY", "Call_Baby" } ,
- { WE_CALLPARENT, "CALLPARENT", "Call_Parent" } ,
+ { WE_BABY, "BABY", "I Love Mama and Fafa" } ,
+ { WE_CALLBABY, "CALLBABY", "Come With Me, Baby" } ,
+ { WE_CALLPARENT, "CALLPARENT", "I Miss My Parents" } ,
{ WE_CALLPARTNER, "CALLPARTNER", "I Want to See You" } ,
{ WE_FEMALE, "FEMALE", "I Only Look Up to You" } ,
{ WE_MALE, "MALE", "I Will Protect You" } ,
@@ -724,7 +500,7 @@ const struct skill_name_db skill_names[] = {
{ WZ_STORMGUST, "STORMGUST", "Storm_Gust" } ,
{ WZ_VERMILION, "VERMILION", "Lord_of_Vermilion" } ,
{ WZ_WATERBALL, "WATERBALL", "Water_Ball" } ,
- { 0, 0, 0 }
+ { 0, 0, 0 }
};
static const int dirx[8]={0,-1,-1,-1,0,1,1,1};
@@ -744,94 +520,49 @@ struct skill_arrow_db skill_arrow_db[MAX_SKILL_ARROW_DB];
/* ƒAƒuƒ‰ƒJƒ_ƒuƒ‰?“®ƒXƒLƒ‹ƒf?ƒ^ƒx?ƒX */
struct skill_abra_db skill_abra_db[MAX_SKILL_ABRA_DB];
-int skill_get_hit( int id ){
- if (id >= 10000 && id < 10015) id -= 9500;
- return skill_db[id].hit;
-}
-int skill_get_inf( int id ){
- return (id < 500) ? skill_db[id].inf : guild_skill_get_inf(id);
-}
-int skill_get_pl( int id ){
- if (id >= 10000 && id < 10015) id-= 9500;
- return skill_db[id].pl;
-}
-int skill_get_nk( int id ){
- if (id >= 10000 && id < 10015) id-= 9500;
- return skill_db[id].nk;
-}
-int skill_get_max( int id ){
- return (id < 500) ? skill_db[id].max : guild_skill_get_max(id);
-}
-int skill_get_range( int id , int lv ){
- if (lv <= 0) return 0;
- return (id < 500) ? skill_db[id].range[lv-1] : guild_skill_get_range(id);
-}
-int skill_get_hp( int id ,int lv ){
- if (id >= 10000 && id < 10015) id-= 9500;
- return (lv <= 0) ? 0: skill_db[id].hp[lv-1];
-}
-int skill_get_sp( int id ,int lv ){
- if (id >= 10000 && id < 10015) id-= 9500;
- //if (lv <= 0) return 0;
- //return (id < 500) ? skill_db[id].sp[lv-1] : guild_skill_get_sp(id, lv);
- return (lv <= 0) ? 0: skill_db[id].sp[lv-1];
-}
-int skill_get_zeny( int id ,int lv ){
- if (id >= 10000 && id < 10015) id-= 9500;
- return (lv <= 0) ? 0:skill_db[id].zeny[lv-1];
-}
-int skill_get_num( int id ,int lv ){
- if (id >= 10000 && id < 10015) id-= 9500;
- return (lv <= 0) ? 0:skill_db[id].num[lv-1];
-}
-int skill_get_cast( int id ,int lv ){
- if (id >= 10000 && id < 10015) id-= 9500;
- return (lv <= 0) ? 0:skill_db[id].cast[lv-1];
-}
-int skill_get_delay( int id ,int lv ){
- if (id >= 10000 && id < 10015) id-= 9500;
- return (lv <= 0) ? 0:skill_db[id].delay[lv-1];
-}
-int skill_get_time( int id ,int lv ){
- if (id >= 10000 && id < 10015) id-= 9500;
- return (lv <= 0) ? 0:skill_db[id].upkeep_time[lv-1];
-}
-int skill_get_time2( int id ,int lv ){
- if (id >= 10000 && id < 10015) id-= 9500;
- return (lv <= 0) ? 0:skill_db[id].upkeep_time2[lv-1];
-}
-int skill_get_castdef( int id ){
- if (id >= 10000 && id < 10015) id-= 9500;
- return skill_db[id].cast_def_rate;
-}
-int skill_get_weapontype( int id ){
- if (id >= 10000 && id < 10015) id-= 9500;
- return skill_db[id].weapon;
-}
-int skill_get_inf2( int id ){
- if (id >= 10000 && id < 10015) id-= 9500;
- return skill_db[id].inf2;
-}
-int skill_get_castcancel( int id ){
- if (id >= 10000 && id < 10015) id-= 9500;
- return skill_db[id].maxcount;
-}
-int skill_get_maxcount( int id ){
- if (id >= 10000 && id < 10015) id-= 9500;
- return skill_db[id].maxcount;
-}
-int skill_get_blewcount( int id ,int lv ){
- if (id >= 10000 && id < 10015) id-= 9500;
- return (lv <= 0) ? 0:skill_db[id].blewcount[lv-1];
-}
-int skill_get_mhp( int id ,int lv ){
- if (id >= 10000 && id < 10015) id-= 9500;
- return (lv <= 0) ? 0:skill_db[id].mhp[lv-1];
-}
-int skill_get_castnodex( int id ,int lv ){
- if (id >= 10000 && id < 10015) id-= 9500;
- return (lv <= 0) ? 0:skill_db[id].castnodex[lv-1];
-}
+// macros to check for out of bounds errors [celest]
+// i: Skill ID, l: Skill Level, var: Value to return after checking
+// for values that don't require level just put a one (putting 0 will trigger return 0; instead
+// for values that might need to use a different function just skill_chk would suffice.
+#define skill_chk(i, l) \
+ if (i >= 10000 && i < 10015) {i -= 9500;} \
+ if (i < 1 || i > MAX_SKILL_DB) {return 0;} \
+ if (l <= 0 || l > MAX_SKILL_LEVEL) {return 0;}
+#define skill_get(var, i, l) \
+ { skill_chk(i, l); return var; }
+
+// Skill DB
+int skill_get_hit( int id ){ skill_get (skill_db[id].hit, id, 1); }
+int skill_get_inf( int id ){ skill_chk (id, 1); return (id < 500) ? skill_db[id].inf : guild_skill_get_inf(id); }
+int skill_get_pl( int id ){ skill_get (skill_db[id].pl, id, 1); }
+int skill_get_nk( int id ){ skill_get (skill_db[id].nk, id, 1); }
+int skill_get_max( int id ){ skill_chk (id, 1); return (id < 500) ? skill_db[id].max : guild_skill_get_max(id); }
+int skill_get_range( int id , int lv ){ skill_chk (id, lv); return (id < 500) ? skill_db[id].range[lv-1] : guild_skill_get_range(id); }
+int skill_get_hp( int id ,int lv ){ skill_get (skill_db[id].hp[lv-1], id, lv); }
+int skill_get_sp( int id ,int lv ){ skill_get (skill_db[id].sp[lv-1], id, lv); }
+int skill_get_zeny( int id ,int lv ){ skill_get (skill_db[id].zeny[lv-1], id, lv); }
+int skill_get_num( int id ,int lv ){ skill_get (skill_db[id].num[lv-1], id, lv); }
+int skill_get_cast( int id ,int lv ){ skill_get (skill_db[id].cast[lv-1], id, lv); }
+int skill_get_delay( int id ,int lv ){ skill_get (skill_db[id].delay[lv-1], id, lv); }
+int skill_get_time( int id ,int lv ){ skill_get (skill_db[id].upkeep_time[lv-1], id, lv); }
+int skill_get_time2( int id ,int lv ){ skill_get (skill_db[id].upkeep_time2[lv-1], id, lv); }
+int skill_get_castdef( int id ){ skill_get (skill_db[id].cast_def_rate, id, 1); }
+int skill_get_weapontype( int id ){ skill_get (skill_db[id].weapon, id, 1); }
+int skill_get_inf2( int id ){ skill_get (skill_db[id].inf2, id, 1); }
+int skill_get_castcancel( int id ){ skill_get (skill_db[id].castcancel, id, 1); }
+int skill_get_maxcount( int id ){ skill_get (skill_db[id].maxcount, id, 1); }
+int skill_get_blewcount( int id ,int lv ){ skill_get (skill_db[id].blewcount[lv-1], id, lv); }
+int skill_get_mhp( int id ,int lv ){ skill_get (skill_db[id].mhp[lv-1], id, lv); }
+int skill_get_castnodex( int id ,int lv ){ skill_get (skill_db[id].castnodex[lv-1], id, lv); }
+int skill_get_delaynodex( int id ,int lv ){ skill_get (skill_db[id].delaynodex[lv-1], id, lv); }
+int skill_get_nocast ( int id ){ skill_get (skill_db[id].nocast, id, 1); }
+int skill_get_unit_id ( int id, int flag ){ skill_get (skill_db[id].unit_id[flag], id, 1); }
+int skill_get_unit_layout_type( int id ,int lv ){ skill_get (skill_db[id].unit_layout_type[lv-1], id, lv); }
+int skill_get_unit_interval( int id ){ skill_get (skill_db[id].unit_interval, id, 1); }
+int skill_get_unit_range( int id ){ skill_get (skill_db[id].unit_range, id, 1); }
+int skill_get_unit_target( int id ){ skill_get (skill_db[id].unit_target, id, 1); }
+int skill_get_unit_flag( int id ){ skill_get (skill_db[id].unit_flag, id, 1); }
+
int skill_tree_get_max(int id, int b_class){
struct pc_base_job s_class = pc_calc_base_job(b_class);
int i, skillid;
@@ -845,42 +576,64 @@ int skill_tree_get_max(int id, int b_class){
int skill_check_condition( struct map_session_data *sd,int type);
int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag );
int skill_frostjoke_scream(struct block_list *bl,va_list ap);
-int skill_status_change_timer_sub(struct block_list *bl, va_list ap );
+int status_change_timer_sub(struct block_list *bl, va_list ap );
int skill_attack_area(struct block_list *bl,va_list ap);
-int skill_abra_dataset(int skilllv);
int skill_clear_element_field(struct block_list *bl);
int skill_landprotector(struct block_list *bl, va_list ap );
int skill_trap_splash(struct block_list *bl, va_list ap );
int skill_count_target(struct block_list *bl, va_list ap );
+struct skill_unit_group_tickset *skill_unitgrouptickset_search(struct block_list *bl,struct skill_unit_group *sg,int tick);
+int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int tick);
+int skill_unit_effect(struct block_list *bl,va_list ap);
+
+int enchant_eff[5] = { 10, 14, 17, 19, 20 };
+int deluge_eff[5] = { 5, 9, 12, 14, 15 };
// [MouseJstr] - skill ok to cast? and when?
-int skillnotok(int skillid, struct map_session_data *sd) {
- if (sd == 0)
- return 0;
- if (pc_isGM(sd) >= 20)
- return 0; // gm's can do anything damn thing they want
+int skillnotok(int skillid, struct map_session_data *sd)
+{
+ nullpo_retr (1, sd);
+ //if (sd == 0)
+ //return 0;
+ //return 1;
+ // I think it was meant to be "no skills allowed when not a valid sd"
+
+ if (!(skillid >= 10000 && skillid < 10015))
+ if ((skillid > MAX_SKILL) || (skillid < 0))
+ return 1;
+
+ {
+ int i = skillid;
+ if (i >= 10000 && i < 10015)
+ i -= 9500;
+ if (sd->blockskill[i] > 0)
+ return 1;
+ }
+
+ if (pc_isGM(sd) >= 20)
+ return 0; // gm's can do anything damn thing they want
// Check skill restrictions [Celest]
- if(!map[sd->bl.m].flag.pvp && !map[sd->bl.m].flag.gvg && skill_db[skillid].nocast & 1)
+ if(!map[sd->bl.m].flag.pvp && !map[sd->bl.m].flag.gvg && skill_get_nocast (skillid) & 1)
return 1;
- if(map[sd->bl.m].flag.pvp && skill_db[skillid].nocast & 2)
+ if(map[sd->bl.m].flag.pvp && skill_get_nocast (skillid) & 2)
return 1;
- if(map[sd->bl.m].flag.gvg && skill_db[skillid].nocast & 4)
+ if(map[sd->bl.m].flag.gvg && skill_get_nocast (skillid) & 4)
return 1;
- if (agit_flag && skill_db[skillid].nocast & 8)
+ if (agit_flag && skill_get_nocast (skillid) & 8)
return 1;
- if (battle_config.pk_mode && !map[sd->bl.m].flag.nopvp && skill_db[skillid].nocast & 16)
+ if (battle_config.pk_mode && !map[sd->bl.m].flag.nopvp && skill_get_nocast (skillid) & 16)
return 1;
-
- switch (skillid) {
- case AL_WARP:
- case AL_TELEPORT:
- case MC_VENDING:
- case MC_IDENTIFY:
- return 0; // always allowed
- default:
- return(map[sd->bl.m].flag.noskill);
- }
+
+ switch (skillid) {
+ case AL_WARP:
+ case AL_TELEPORT:
+ case MC_VENDING:
+ case MC_IDENTIFY:
+ return 0; // always allowed
+ default:
+ return (map[sd->bl.m].flag.noskill);
+ }
}
@@ -888,105 +641,58 @@ static int distance(int x0,int y0,int x1,int y1)
{
int dx,dy;
- dx=abs(x0-x1);
- dy=abs(y0-y1);
- return dx>dy ? dx : dy;
+ dx = abs(x0 - x1);
+ dy = abs(y0 - y1);
+ return dx > dy ? dx : dy;
}
-/* ƒXƒLƒ‹ƒ†ƒjƒbƒgID‚ð•Ô‚·i‚±‚ê‚àƒf?ƒ^ƒx?ƒX‚É“ü‚ꂽ‚¢‚Èj */
-int skill_get_unit_id(int id,int flag)
-{
+/* ƒXƒLƒ‹ƒ†ƒjƒbƒg‚Ì”z’uî•ñ‚ð•Ô‚· */
+struct skill_unit_layout skill_unit_layout[MAX_SKILL_UNIT_LAYOUT];
+int firewall_unit_pos;
+int icewall_unit_pos;
- switch(id){
- case MG_SAFETYWALL: return 0x7e; /* ƒZƒCƒtƒeƒBƒEƒH?ƒ‹ */
- case MG_FIREWALL: return 0x7f; /* ƒtƒ@ƒCƒA?ƒEƒH?ƒ‹ */
- case AL_WARP: return (flag==0)?0x81:0x80; /* ƒ?ƒvƒ|?ƒ^ƒ‹ */
- case PR_BENEDICTIO: return 0x82; /* ¹?~•Ÿ */
- case PR_SANCTUARY: return 0x83; /* ƒTƒ“ƒNƒ`ƒ…ƒAƒŠ */
- case PR_MAGNUS: return 0x84; /* ƒ}ƒOƒkƒXƒGƒNƒ\ƒVƒYƒ€ */
- case AL_PNEUMA: return 0x85; /* ƒjƒ…?ƒ} */
- case MG_THUNDERSTORM: return 0x86; /* ƒTƒ“ƒ_?ƒXƒg?ƒ€ */
- case WZ_HEAVENDRIVE: return 0x86; /* ƒwƒ”ƒ“ƒYƒhƒ‰ƒCƒu */
- case WZ_SIGHTRASHER: return 0x86; /* ƒTƒCƒgƒ‰ƒbƒVƒƒ? */
- case WZ_METEOR: return 0x86; /* ƒƒeƒIƒXƒg?ƒ€ */
- case WZ_VERMILION: return 0x86; /* ƒ?ƒhƒIƒuƒ”ƒ@?ƒ~ƒŠƒIƒ“ */
- case WZ_FROSTNOVA: return 0x86; /* ƒtƒƒXƒgƒmƒ”ƒ@ */
- case WZ_STORMGUST: return 0x86; /* ƒXƒg?ƒ€ƒKƒXƒg(‚Ƃ肠‚¦‚¸LoV‚Æ“¯‚¶‚Å?—) */
- case CR_GRANDCROSS: return 0x86; /* ƒOƒ‰ƒ“ƒhƒNƒƒX */
- case WZ_FIREPILLAR: return (flag==0)?0x87:0x88; /* ƒtƒ@ƒCƒA?ƒsƒ‰? */
- case HT_TALKIEBOX: return 0x99; /* ƒg?ƒL?ƒ{ƒbƒNƒX */
- case WZ_ICEWALL: return 0x8d; /* ƒAƒCƒXƒEƒH?ƒ‹ */
- case WZ_QUAGMIRE: return 0x8e; /* ƒNƒ@ƒOƒ}ƒCƒA */
- case HT_BLASTMINE: return 0x8f; /* ƒuƒ‰ƒXƒgƒ}ƒCƒ“ */
- case HT_SKIDTRAP: return 0x90; /* ƒXƒLƒbƒhƒgƒ‰ƒbƒv */
- case HT_ANKLESNARE: return 0x91; /* ƒAƒ“ƒNƒ‹ƒXƒlƒA */
- case AS_VENOMDUST: return 0x92; /* ƒxƒmƒ€ƒ_ƒXƒg */
- case HT_LANDMINE: return 0x93; /* ƒ‰ƒ“ƒhƒ}ƒCƒ“ */
- case HT_SHOCKWAVE: return 0x94; /* ƒVƒ‡ƒbƒNƒEƒF?ƒuƒgƒ‰ƒbƒv */
- case HT_SANDMAN: return 0x95; /* ƒTƒ“ƒhƒ}ƒ“ */
- case HT_FLASHER: return 0x96; /* ƒtƒ‰ƒbƒVƒƒ? */
- case HT_FREEZINGTRAP: return 0x97; /* ƒtƒŠ?ƒWƒ“ƒOƒgƒ‰ƒbƒv */
- case HT_CLAYMORETRAP: return 0x98; /* ƒNƒŒƒCƒ‚ƒA?ƒgƒ‰ƒbƒv */
- case SA_VOLCANO: return 0x9a; /* ƒ{ƒ‹ƒP?ƒm */
- case SA_DELUGE: return 0x9b; /* ƒfƒŠƒ…?ƒW */
- case SA_VIOLENTGALE: return 0x9c; /* ƒoƒCƒIƒŒƒ“ƒgƒQƒCƒ‹ */
- case SA_LANDPROTECTOR: return 0x9d; /* ƒ‰ƒ“ƒhƒvƒƒeƒNƒ^? */
- case BD_LULLABY: return 0x9e; /* ŽqŽç‰Ì */
- case BD_RICHMANKIM: return 0x9f; /* ƒjƒˆƒ‹ƒh‚̉ƒ */
- case BD_ETERNALCHAOS: return 0xa0; /* ‰i‰“‚̬“× */
- case BD_DRUMBATTLEFIELD:return 0xa1; /* ?‘¾ŒÛ‚Ì‹¿‚« */
- case BD_RINGNIBELUNGEN: return 0xa2; /* ƒj?ƒxƒ‹ƒ“ƒO‚ÌŽw—Ö */
- case BD_ROKISWEIL: return 0xa3; /* ƒƒL‚Ì‹©‚Ñ */
- case BD_INTOABYSS: return 0xa4; /* [•£‚Ì’†‚É */
- case BD_SIEGFRIED: return 0xa5; /* •sŽ€g‚̃W?ƒNƒtƒŠ?ƒh */
- case BA_DISSONANCE: return 0xa6; /* •s‹¦˜a‰¹ */
- case BA_WHISTLE: return 0xa7; /* Œû“J */
- case BA_ASSASSINCROSS: return 0xa8; /* —[—z‚̃AƒTƒVƒ“ƒNƒƒX */
- case BA_POEMBRAGI: return 0xa9; /* ƒuƒ‰ƒM‚ÌŽ */
- case BA_APPLEIDUN: return 0xaa; /* ƒCƒhƒDƒ“‚Ì—ÑŒç */
- case DC_UGLYDANCE: return 0xab; /* Ž©•ªŸŽè‚ȃ_ƒ“ƒX */
- case DC_HUMMING: return 0xac; /* ƒnƒ~ƒ“ƒO */
- case DC_DONTFORGETME: return 0xad; /* Ž„‚ð–Y‚ê‚È‚¢‚Åc */
- case DC_FORTUNEKISS: return 0xae; /* K‰^‚̃LƒX */
- case DC_SERVICEFORYOU: return 0xaf; /* ƒT?ƒrƒXƒtƒH?ƒ†? */
- case RG_GRAFFITI: return 0xb0; /* ƒOƒ‰ƒtƒBƒeƒB */
- case AM_DEMONSTRATION: return 0xb1; /* ƒfƒ‚ƒ“ƒXƒgƒŒ?ƒVƒ‡ƒ“ */
- case WE_CALLPARTNER: return 0xb2; /* ‚ ‚È‚½‚Ɉ§‚¢‚½‚¢ */
- case PA_GOSPEL: return 0xb3; /* ƒSƒXƒyƒ‹ */
- case HP_BASILICA: return 0xb4; /* ƒoƒWƒŠƒJ */
- case CG_MOONLIT: return 0xb5;
- case PF_FOGWALL: return 0xb6; /* ƒtƒHƒOƒEƒH?ƒ‹ */
- case PF_SPIDERWEB: return 0xb7; /* ƒXƒpƒCƒ_?ƒEƒFƒbƒu */
- // temporary unit ID's [Celest]
- case GD_LEADERSHIP: return 0xc1;
- case GD_GLORYWOUNDS: return 0xc2;
- case GD_SOULCOLD: return 0xc3;
- case GD_HAWKEYES: return 0xc4;
- }
- return 0;
- /*
- 0x89,0x8a,0x8b •\ަ–³‚µ
- 0x9a ‰Š?«‚̉r¥‚Ý‚½‚¢‚ȃGƒtƒFƒNƒg
- 0x9b …?«‚̉r¥‚Ý‚½‚¢‚ȃGƒtƒFƒNƒg
- 0x9c •—?«‚̉r¥‚Ý‚½‚¢‚ȃGƒtƒFƒNƒg
- 0x9d ”’‚¢¬‚³‚ȃGƒtƒFƒNƒg
- 0xb1 Alchemist Demonstration
- 0xb2 = Pink Warp Portal
- 0xb3 = Gospel For Paladin
- 0xb4 = Basilica
- 0xb5 = Empty
- 0xb6 = Fog Wall for Professor
- 0xb7 = Spider Web for Professor
- 0xb8 = Empty
- 0xb9 =
- */
+struct skill_unit_layout *skill_get_unit_layout (int skillid, int skilllv, struct block_list *src, int x, int y)
+{
+ int pos = skill_get_unit_layout_type(skillid,skilllv);
+ int dir;
+
+ if (pos != -1)
+ return &skill_unit_layout[pos];
+
+ if (src->x == x && src->y == y)
+ dir = 2;
+ else
+ dir = map_calc_dir(src,x,y);
+
+ if (skillid == MG_FIREWALL)
+ return &skill_unit_layout [firewall_unit_pos + dir];
+ else if (skillid == WZ_ICEWALL)
+ return &skill_unit_layout [icewall_unit_pos + dir];
+
+ printf("Unknown unit layout for skill %d, %d\n",skillid,skilllv);
+ return &skill_unit_layout[0];
}
+// 0x89,0x8a,0x8b •\ަ–³‚µ
+// 0x9a ‰Š?«‚̉r¥‚Ý‚½‚¢‚ȃGƒtƒFƒNƒg
+// 0x9b …?«‚̉r¥‚Ý‚½‚¢‚ȃGƒtƒFƒNƒg
+// 0x9c •—?«‚̉r¥‚Ý‚½‚¢‚ȃGƒtƒFƒNƒg
+// 0x9d ”’‚¢¬‚³‚ȃGƒtƒFƒNƒg
+// 0xb1 Alchemist Demonstration
+// 0xb2 = Pink Warp Portal
+// 0xb3 = Gospel For Paladin
+// 0xb4 = Basilica
+// 0xb5 = Empty
+// 0xb6 = Fog Wall for Professor
+// 0xb7 = Spider Web for Professor
+// 0xb8 = Empty
+// 0xb9 =
+
/*==========================================
* ƒXƒLƒ‹’ljÁ?‰Ê
*------------------------------------------
*/
-int skill_additional_effect( struct block_list* src, struct block_list *bl,int skillid,int skilllv,int attack_type,unsigned int tick)
+int skill_additional_effect (struct block_list* src, struct block_list *bl, int skillid, int skilllv, int attack_type, unsigned int tick)
{
/* MOB’ljÁ?‰ÊƒXƒLƒ‹—p */
const int sc[]={
@@ -1006,7 +712,7 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s
struct pet_data *pd=NULL;
int skill,skill2;
- int rate,luk;
+ int rate;
int sc_def_mdef,sc_def_vit,sc_def_int,sc_def_luk;
int sc_def_mdef2,sc_def_vit2,sc_def_int2,sc_def_luk2;
@@ -1014,102 +720,83 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s
nullpo_retr(0, src);
nullpo_retr(0, bl);
- //if(skilllv <= 0) return 0;
+ if(skillid < 0)
+ { // remove the debug print when this case is finished
+ printf("skill_additional_effect: skillid=%i\ncall: %p %p %i %i %i %i",skillid,
+ src, bl,skillid,skilllv,attack_type,tick);
+ return 0;
+ }
if(skillid > 0 && skilllv <= 0) return 0; // don't forget auto attacks! - celest
- if(src->type==BL_PC){
- nullpo_retr(0, sd=(struct map_session_data *)src);
- }else if(src->type==BL_MOB){
- nullpo_retr(0, md=(struct mob_data *)src); //–¢Žg—pH
- }else if(src->type==BL_PET){
- nullpo_retr(0, pd=(struct pet_data *)src); // [Valaris]
+ if (src->type == BL_PC){
+ nullpo_retr(0, sd = (struct map_session_data *)src);
+ } else if (src->type == BL_MOB){
+ nullpo_retr(0, md = (struct mob_data *)src); //–¢Žg—pH
+ } else if (src->type == BL_PET){
+ nullpo_retr(0, pd = (struct pet_data *)src); // [Valaris]
+ }
+
+ if(bl->type == BL_PC) {
+ nullpo_retr(0, dstsd=(struct map_session_data *)bl);
+ } else if(bl->type == BL_MOB) {
+ nullpo_retr(0, dstmd=(struct mob_data *)bl); //–¢Žg—pH
}
//?ۂ̑ϫ
- luk = battle_get_luk(bl);
- sc_def_mdef=100 - (3 + battle_get_mdef(bl) + luk/3);
- sc_def_vit=100 - (3 + battle_get_vit(bl) + luk/3);
- sc_def_int=100 - (3 + battle_get_int(bl) + luk/3);
- sc_def_luk=100 - (3 + luk);
+ sc_def_mdef = status_get_sc_def_mdef(bl);
+ sc_def_vit = status_get_sc_def_vit(bl);
+ sc_def_int = status_get_sc_def_int(bl);
+ sc_def_luk = status_get_sc_def_luk(bl);
+
//Ž©•ª‚̑ϫ
- luk = battle_get_luk(src);
- sc_def_mdef2=100 - (3 + battle_get_mdef(src) + luk/3);
- sc_def_vit2=100 - (3 + battle_get_vit(src) + luk/3);
- sc_def_int2=100 - (3 + battle_get_int(src) + luk/3);
- sc_def_luk2=100 - (3 + luk);
- if(bl->type==BL_PC)
- dstsd=(struct map_session_data *)bl;
- else if(bl->type==BL_MOB){
- dstmd=(struct mob_data *)bl; //–¢Žg—pH
- if(sc_def_mdef<50)
- sc_def_mdef=50;
- if(sc_def_vit<50)
- sc_def_vit=50;
- if(sc_def_int<50)
- sc_def_int=50;
- if(sc_def_luk<50)
- sc_def_luk=50;
- }
- if(sc_def_mdef<0)
- sc_def_mdef=0;
- if(sc_def_vit<0)
- sc_def_vit=0;
- if(sc_def_int<0)
- sc_def_int=0;
+ sc_def_mdef2 = status_get_sc_def_mdef(src);
+ sc_def_vit2 = status_get_sc_def_vit(src);
+ sc_def_int2 = status_get_sc_def_int(src);
+ sc_def_luk2 = status_get_sc_def_luk(src);
switch(skillid){
case 0: /* ’ÊíU? */
/* Ž©“®‘é */
- if( sd && pc_isfalcon(sd) && sd->status.weapon == 11 && (skill=pc_checkskill(sd,HT_BLITZBEAT))>0 &&
- rand()%1000 <= sd->paramc[5]*10/3+1 ) {
- int lv=(sd->status.job_level+9)/10;
- skill_castend_damage_id(src,bl,HT_BLITZBEAT,(skill<lv)?skill:lv,tick,0xf00000);
- }
- // ƒXƒiƒbƒ`ƒƒ?
- if(sd && sd->status.weapon != 11 && (skill=pc_checkskill(sd,RG_SNATCHER)) > 0)
- if((skill*15 + 55) + (skill2 = pc_checkskill(sd,TF_STEAL))*10 > rand()%1000) {
+ if(sd) {
+ struct status_change *sc_data = status_get_sc_data(bl);
+ if (pc_isfalcon(sd) && sd->status.weapon == 11 && (skill=pc_checkskill(sd,HT_BLITZBEAT))>0 &&
+ rand()%1000 <= sd->paramc[5]*10/3+1 ) {
+ int lv=(sd->status.job_level+9)/10;
+ skill_castend_damage_id(src,bl,HT_BLITZBEAT,(skill<lv)?skill:lv,tick,0xf00000);
+ }
+ // ƒXƒiƒbƒ`ƒƒ?
+ if(sd->status.weapon != 11 && (skill=pc_checkskill(sd,RG_SNATCHER)) > 0 &&
+ (skill*15 + 55) + (skill2 = pc_checkskill(sd,TF_STEAL))*10 > rand()%1000) {
if(pc_steal_item(sd,bl))
clif_skill_nodamage(src,bl,TF_STEAL,skill2,1);
else if (battle_config.display_snatcher_skill_fail)
- clif_skill_fail(sd,skillid,0,0); // it's annoying! =p [Celest]
- }
- // ƒGƒ“ƒ`ƒƒƒ“ƒgƒfƒbƒgƒŠ?ƒ|ƒCƒYƒ“(–Ò“Å?‰Ê)
- if (sd && sd->sc_data[SC_EDP].timer != -1 && rand() % 10000 < sd->sc_data[SC_EDP].val2 * sc_def_vit) {
- int mhp = battle_get_max_hp(bl);
- int hp = battle_get_hp(bl);
- int lvl = sd->sc_data[SC_EDP].val1;
- int diff;
- // MHP‚Ì1/4ˆÈ‰º‚ɂ͂Ȃç‚È‚¢
- if(hp > mhp>>2) {
- if(bl->type == BL_PC) {
- diff = mhp*10/100;
- if (hp - diff < mhp>>2)
- diff = hp - (mhp>>2);
- pc_heal((struct map_session_data *)bl, -hp, 0);
- } else if(bl->type == BL_MOB) {
- struct mob_data *md = (struct mob_data *)bl;
- hp -= mhp*15/100;
- if (hp > mhp>>2)
- md->hp = hp;
- else
- md->hp = mhp>>2;
- }
+ clif_skill_fail(sd,skillid,0,0);
+ }
+ // enchant poison has a chance of poisoning enemy
+ if (sd->sc_data[SC_ENCPOISON].timer != -1 && sc_data && sc_data[SC_POISON].timer == -1 &&
+ rand() % 100 < sd->sc_data[SC_ENCPOISON].val1 * sc_def_vit / 100) {
+ status_change_start(bl,SC_POISON,sd->sc_data[SC_ENCPOISON].val1,
+ 0,0,0,skill_get_time2(AS_ENCHANTPOISON,sd->sc_data[SC_ENCPOISON].val1),0);
}
- skill_status_change_start(bl,SC_DPOISON,lvl,0,0,0,skill_get_time2(ASC_EDP,lvl),0);
+ // ƒGƒ“ƒ`ƒƒƒ“ƒgƒfƒbƒgƒŠ?ƒ|ƒCƒYƒ“(–Ò“Å?‰Ê)
+ if (sd->sc_data[SC_EDP].timer != -1 && sc_data && sc_data[SC_DPOISON].timer == -1 &&
+ rand() % 100 < sd->sc_data[SC_EDP].val2 * sc_def_vit / 100)
+ status_change_start(bl,SC_DPOISON,sd->sc_data[SC_EDP].val1,
+ 0,0,0,skill_get_time2(ASC_EDP,sd->sc_data[SC_EDP].val1),0);
}
break;
case SM_BASH: /* ƒoƒbƒVƒ…i‹}ŠU?j */
if( sd && (skill=pc_checkskill(sd,SM_FATALBLOW))>0 ){
if( rand()%100 < 6*(skilllv-5)*sc_def_vit/100 )
- skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(SM_FATALBLOW,skilllv),0);
+ status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(SM_FATALBLOW,skilllv),0);
}
break;
case TF_POISON: /* ƒCƒ“ƒxƒiƒ€ */
case AS_SPLASHER: /* ƒxƒiƒ€ƒXƒvƒ‰ƒbƒVƒƒ? */
if(rand()%100< (2*skilllv+10)*sc_def_vit/100 )
- skill_status_change_start(bl,SC_POISON,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_POISON,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
else{
if(sd && skillid==TF_POISON)
clif_skill_fail(sd,skillid,0,0);
@@ -1118,122 +805,140 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s
case AS_SONICBLOW: /* ƒ\ƒjƒbƒNƒuƒ? */
if( rand()%100 < (2*skilllv+10)*sc_def_vit/100 )
- skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ break;
+
+ case AS_GRIMTOOTH:
+ if (bl->type == BL_MOB) {
+ struct status_change *sc_data = status_get_sc_data(bl);
+ if (sc_data && sc_data[SC_SLOWDOWN].timer == -1)
+ status_change_start(bl,SC_SLOWDOWN,0,0,0,0,1000,0);
+ }
break;
case HT_FREEZINGTRAP: /* ƒtƒŠ?ƒWƒ“ƒOƒgƒ‰ƒbƒv */
rate=skilllv*3+35;
if(rand()%100 < rate*sc_def_mdef/100)
- skill_status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case MG_FROSTDIVER: /* ƒtƒƒXƒgƒ_ƒCƒo? */
case WZ_FROSTNOVA: /* ƒtƒƒXƒgƒmƒ”ƒ@ */
- rate=(skilllv*3+35)*sc_def_mdef/100-(battle_get_int(bl)+battle_get_luk(bl))/15;
- rate=rate<=5?5:rate;
- if(rand()%100 < rate)
- skill_status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
- else if(sd && skillid==MG_FROSTDIVER)
- clif_skill_fail(sd,skillid,0,0);
+ {
+ struct status_change *sc_data = status_get_sc_data(bl);
+ rate = (skilllv*3+35)*sc_def_mdef/100-(status_get_int(bl)+status_get_luk(bl))/15;
+ if (rate <= 5)
+ rate = 5;
+ if(sc_data && sc_data[SC_FREEZE].timer == -1 && rand()%100 < rate)
+ status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv)*(1-sc_def_mdef/100),0);
+ else if (sd && skillid == MG_FROSTDIVER)
+ clif_skill_fail(sd,skillid,0,0);
+ }
break;
case WZ_STORMGUST: /* ƒXƒg?ƒ€ƒKƒXƒg */
{
- struct status_change *sc_data = battle_get_sc_data(bl);
+ struct status_change *sc_data = status_get_sc_data(bl);
if(sc_data) {
sc_data[SC_FREEZE].val3++;
if(sc_data[SC_FREEZE].val3 >= 3)
- skill_status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
}
}
break;
case HT_LANDMINE: /* ƒ‰ƒ“ƒhƒ}ƒCƒ“ */
if( rand()%100 < (5*skilllv+30)*sc_def_vit/100 )
- skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case HT_SHOCKWAVE: /* ƒVƒ‡ƒbƒNƒEƒF?ƒuƒgƒ‰ƒbƒv */
if(map[bl->m].flag.pvp && dstsd){
dstsd->status.sp -= dstsd->status.sp*(5+15*skilllv)/100;
- pc_calcstatus(dstsd,0);
+ status_calc_pc(dstsd,0);
}
break;
case HT_SANDMAN: /* ƒTƒ“ƒhƒ}ƒ“ */
if( rand()%100 < (5*skilllv+30)*sc_def_int/100 )
- skill_status_change_start(bl,SC_SLEEP,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_SLEEP,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case TF_SPRINKLESAND: /* »‚Ü‚« */
if( rand()%100 < 20*sc_def_int/100 )
- skill_status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case TF_THROWSTONE: /* Î“Š‚° */
if( rand()%100 < 7*sc_def_vit/100 )
- skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case CR_HOLYCROSS: /* ƒz?ƒŠ?ƒNƒƒX */
if( rand()%100 < 3*skilllv*sc_def_int/100 )
- skill_status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case CR_GRANDCROSS: /* ƒOƒ‰ƒ“ƒhƒNƒƒX */
+ case NPC_DARKGRANDCROSS: /*ˆÅƒOƒ‰ƒ“ƒhƒNƒƒX*/
{
- int race = battle_get_race(bl);
- if( (battle_check_undead(race,battle_get_elem_type(bl)) || race == 6) && rand()%100 < 100000*sc_def_int/100) //?§•t?‚¾‚ªŠ®‘S‘Ï«‚ɂ͖³?
- skill_status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ int race = status_get_race(bl);
+ if( (battle_check_undead(race,status_get_elem_type(bl)) || race == 6) && rand()%100 < 100000*sc_def_int/100) //?§•t?‚¾‚ªŠ®‘S‘Ï«‚ɂ͖³?
+ status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
}
break;
+ case AM_ACIDTERROR:
+ if( rand()%100 < (skilllv*3)*sc_def_vit/100 )
+ status_change_start(bl,SC_BLEEDING,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ break;
+
case CR_SHIELDCHARGE: /* ƒV?ƒ‹ƒhƒ`ƒƒ?ƒW */
if( rand()%100 < (15 + skilllv*5)*sc_def_vit/100 )
- skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case RG_RAID: /* ƒTƒvƒ‰ƒCƒYƒAƒ^ƒbƒN */
if( rand()%100 < (10+3*skilllv)*sc_def_vit/100 )
- skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
if( rand()%100 < (10+3*skilllv)*sc_def_int/100 )
- skill_status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case BA_FROSTJOKE:
if(rand()%100 < (15+5*skilllv)*sc_def_mdef/100)
- skill_status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case DC_SCREAM:
if( rand()%100 < (25+5*skilllv)*sc_def_vit/100 )
- skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case BD_LULLABY: /* ŽqŽç‰S */
if( rand()%100 < 15*sc_def_int/100 )
- skill_status_change_start(bl,SC_SLEEP,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_SLEEP,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
/* MOB‚̒ljÁ?‰Ê•t‚«ƒXƒLƒ‹ */
case NPC_PETRIFYATTACK:
if(rand()%100 < sc_def_mdef)
- skill_status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case NPC_POISON:
case NPC_SILENCEATTACK:
case NPC_STUNATTACK:
if(rand()%100 < sc_def_vit && src->type!=BL_PET)
- skill_status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
if(src->type==BL_PET)
- skill_status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skilllv*1000,0);
+ status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skilllv*1000,0);
break;
case NPC_CURSEATTACK:
if(rand()%100 < sc_def_luk)
- skill_status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case NPC_SLEEPATTACK:
case NPC_BLINDATTACK:
if(rand()%100 < sc_def_int)
- skill_status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case NPC_MENTALBREAKER:
if(dstsd) {
@@ -1247,126 +952,164 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s
//
case WZ_METEOR:
if(rand()%100 < sc_def_vit)
- skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case WZ_VERMILION:
if(rand()%100 < sc_def_int)
- skill_status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
// -- moonsoul (stun ability of new champion skill tigerfist)
//
case CH_TIGERFIST:
- if( rand()%100 < (10 + skilllv*10)*sc_def_vit/100 )
- skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ if (rand()%100 < (10 + skilllv*10)*sc_def_vit/100) {
+ int sec = skill_get_time2 (skillid,skilllv) - status_get_agi(bl)/10;
+ if (dstsd) {
+ dstsd->canmove_tick += sec;
+ dstsd->canact_tick += sec;
+ } else if (dstmd)
+ dstmd->canmove_tick += sec;
+ }
break;
case LK_SPIRALPIERCE:
if( rand()%100 < (15 + skilllv*5)*sc_def_vit/100 )
- skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case ST_REJECTSWORD: /* ƒtƒŠ?ƒWƒ“ƒOƒgƒ‰ƒbƒv */
if( rand()%100 < (skilllv*15) )
- skill_status_change_start(bl,SC_AUTOCOUNTER,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_AUTOCOUNTER,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case PF_FOGWALL: /* ƒz?ƒŠ?ƒNƒƒX */
- if( rand()%100 < 3*skilllv*sc_def_int/100 )
- skill_status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ if (src != bl) {
+ struct status_change *sc_data = status_get_sc_data(bl);
+ if (sc_data && sc_data[SC_DELUGE].timer == -1)
+ status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ }
break;
case LK_HEADCRUSH: /* ƒwƒbƒhƒNƒ‰ƒbƒVƒ… */
{//?Œ‚ª—Ç‚­•ª‚©‚ç‚È‚¢‚̂œK?‚É
- int race=battle_get_race(bl);
- if( !(battle_check_undead(race,battle_get_elem_type(bl)) || race == 6) && rand()%100 < (2*skilllv+10)*sc_def_vit/100 )
- skill_status_change_start(bl,SC_HEADCRUSH,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ int race=status_get_race(bl);
+ if( !(battle_check_undead(race,status_get_elem_type(bl)) || race == 6) && rand()%100 < (2*skilllv+10)*sc_def_vit/100 )
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
}
break;
case LK_JOINTBEAT: /* ƒWƒ‡ƒCƒ“ƒgƒr?ƒg */
//?Œ‚ª—Ç‚­•ª‚©‚ç‚È‚¢‚̂œK?‚É
- if( rand()%100 < (2*skilllv+10)*sc_def_vit/100 )
- skill_status_change_start(bl,SC_JOINTBEAT,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ if( rand()%100 < (5*skilllv+5)*sc_def_vit/100 )
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case PF_SPIDERWEB: /* ƒXƒpƒCƒ_?ƒEƒFƒbƒu */
{
- if(bl->type == BL_MOB)
- {
- int sec=skill_get_time2(skillid,skilllv);
- if(map[src->m].flag.pvp) //PvP‚Å‚ÍS‘©ŽžŠÔ”¼Œ¸H
- sec = sec/2;
- battle_stopwalking(bl,1);
- skill_status_change_start(bl,SC_SPIDERWEB,skilllv,0,0,0,sec,0);
- }
+ int sec = skill_get_time2(skillid,skilllv);
+ if(map[src->m].flag.pvp) //PvP‚Å‚ÍS‘©ŽžŠÔ”¼Œ¸H
+ sec = sec/2;
+ battle_stopwalking(bl,1);
+ status_change_start(bl,SC_SPIDERWEB,skilllv,0,0,0,sec,0);
}
break;
case ASC_METEORASSAULT: /* ƒƒeƒIƒAƒTƒ‹ƒg */
if( rand()%100 < (15 + skilllv*5)*sc_def_vit/100 ) //?‘ÔˆÙí‚ÍÚׂª•ª‚©‚ç‚È‚¢‚̂œK?‚É
- skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
if( rand()%100 < (10+3*skilllv)*sc_def_int/100 )
- skill_status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case MO_EXTREMITYFIST: /* ˆ¢C—…”e™€Œ */
//ˆ¢C—…‚ðŽg‚¤‚Æ5•ªŠÔŽ©‘R‰ñ•œ‚µ‚È‚¢‚悤‚ɂȂé
- skill_status_change_start(src,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0 );
+ status_change_start(src,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0 );
break;
case HW_NAPALMVULCAN: /* ƒiƒp?ƒ€ƒoƒ‹ƒJƒ“ */
// skilllv*5%‚ÌŠm—¦‚ÅŽô‚¢
if (rand()%10000 < 5*skilllv*sc_def_luk)
- skill_status_change_start(bl,SC_CURSE,7,0,0,0,skill_get_time2(NPC_CURSEATTACK,7),0);
+ status_change_start(bl,SC_CURSE,7,0,0,0,skill_get_time2(NPC_CURSEATTACK,7),0);
break;
}
- if(sd && skillid != MC_CARTREVOLUTION && attack_type&BF_WEAPON){ /* ƒJ?ƒh‚É‚æ‚é’ljÁ?‰Ê */
- int i;
+ if((sd||dstsd) && skillid != MC_CARTREVOLUTION && attack_type&BF_WEAPON){ /* ƒJ?ƒh‚É‚æ‚é’ljÁ?‰Ê */
+ int i, type;
int sc_def_card=100;
for(i=SC_STONE;i<=SC_BLIND;i++){
+ type=i-SC_STONE;
//?Û‚É?‘ÔˆÙí
- if(i==SC_STONE || i==SC_FREEZE)
- sc_def_card=sc_def_mdef;
- else if(i==SC_STAN || i==SC_POISON || i==SC_SILENCE)
- sc_def_card=sc_def_vit;
- else if(i==SC_SLEEP || i==SC_CONFUSION || i==SC_BLIND)
- sc_def_card=sc_def_int;
- else if(i==SC_CURSE)
- sc_def_card=sc_def_luk;
-
- if(!sd->state.arrow_atk) {
- if(rand()%10000 < (sd->addeff[i-SC_STONE])*sc_def_card/100 ){
- if(battle_config.battle_log)
- printf("PC %d skill_addeff: card‚É‚æ‚éˆÙí?“® %d %d\n",sd->bl.id,i,sd->addeff[i-SC_STONE]);
- skill_status_change_start(bl,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0);
- }
+ switch (i) {
+ case SC_STONE:
+ case SC_FREEZE:
+ sc_def_card=sc_def_mdef;
+ break;
+ case SC_STAN:
+ case SC_POISON:
+ case SC_SILENCE:
+ sc_def_card=sc_def_vit;
+ break;
+ case SC_SLEEP:
+ case SC_CONFUSION:
+ case SC_BLIND:
+ sc_def_card=sc_def_int;
+ break;
+ case SC_CURSE:
+ sc_def_card=sc_def_luk;
}
- else {
- if(rand()%10000 < (sd->addeff[i-SC_STONE]+sd->arrow_addeff[i-SC_STONE])*sc_def_card/100 ){
- if(battle_config.battle_log)
- printf("PC %d skill_addeff: card‚É‚æ‚éˆÙí?“® %d %d\n",sd->bl.id,i,sd->addeff[i-SC_STONE]);
- skill_status_change_start(bl,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0);
+
+ if (sd) {
+ if(!sd->state.arrow_atk) {
+ if(rand()%10000 < (sd->addeff[type])*sc_def_card/100 ){
+ if(battle_config.battle_log)
+ printf("PC %d skill_addeff: card‚É‚æ‚éˆÙí?“® %d %d\n",sd->bl.id,i,sd->addeff[type]);
+ status_change_start(bl,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[type],7),0);
+ }
+ }
+ else {
+ if(rand()%10000 < (sd->addeff[type]+sd->arrow_addeff[type])*sc_def_card/100 ){
+ if(battle_config.battle_log)
+ printf("PC %d skill_addeff: card‚É‚æ‚éˆÙí?“® %d %d\n",sd->bl.id,i,sd->addeff[type]);
+ status_change_start(bl,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[type],7),0);
+ }
}
}
//Ž©•ª‚É?‘ÔˆÙí
- if(i==SC_STONE || i==SC_FREEZE)
- sc_def_card=sc_def_mdef2;
- else if(i==SC_STAN || i==SC_POISON || i==SC_SILENCE)
- sc_def_card=sc_def_vit2;
- else if(i==SC_SLEEP || i==SC_CONFUSION || i==SC_BLIND)
- sc_def_card=sc_def_int2;
- else if(i==SC_CURSE)
- sc_def_card=sc_def_luk2;
-
- if(!sd->state.arrow_atk) {
- if(rand()%10000 < (sd->addeff2[i-SC_STONE])*sc_def_card/100 ){
- if(battle_config.battle_log)
- printf("PC %d skill_addeff: card‚É‚æ‚éˆÙí?“® %d %d\n",src->id,i,sd->addeff2[i-SC_STONE]);
- skill_status_change_start(src,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0);
- }
+ switch (i) {
+ case SC_STONE:
+ case SC_FREEZE:
+ sc_def_card=sc_def_mdef2;
+ break;
+ case SC_STAN:
+ case SC_POISON:
+ case SC_SILENCE:
+ sc_def_card=sc_def_vit2;
+ break;
+ case SC_SLEEP:
+ case SC_CONFUSION:
+ case SC_BLIND:
+ sc_def_card=sc_def_int2;
+ break;
+ case SC_CURSE:
+ sc_def_card=sc_def_luk2;
}
- else {
- if(rand()%10000 < (sd->addeff2[i-SC_STONE]+sd->arrow_addeff2[i-SC_STONE])*sc_def_card/100 ){
- if(battle_config.battle_log)
- printf("PC %d skill_addeff: card‚É‚æ‚éˆÙí?“® %d %d\n",src->id,i,sd->addeff2[i-SC_STONE]);
- skill_status_change_start(src,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0);
+
+ if (sd) {
+ if(!sd->state.arrow_atk) {
+ if(rand()%10000 < (sd->addeff2[type])*sc_def_card/100 ){
+ if(battle_config.battle_log)
+ printf("PC %d skill_addeff: card‚É‚æ‚éˆÙí?“® %d %d\n",src->id,i,sd->addeff2[type]);
+ status_change_start(src,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[type],7),0);
+ }
+ }
+ else {
+ if(rand()%10000 < (sd->addeff2[type]+sd->arrow_addeff2[type])*sc_def_card/100 ){
+ if(battle_config.battle_log)
+ printf("PC %d skill_addeff: card‚É‚æ‚éˆÙí?“® %d %d\n",src->id,i,sd->addeff2[type]);
+ status_change_start(src,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[type],7),0);
+ }
}
}
+ if (dstsd && rand()%10000 < dstsd->addeff3[type]*sc_def_card/100){
+ if (dstsd->addeff3_type[type] != 1 && ((sd && !sd->state.arrow_atk) || (status_get_range(src)<=2)))
+ continue;
+ if(battle_config.battle_log)
+ printf("PC %d skill_addeff: card‚É‚æ‚éˆÙí?“® %d %d\n",src->id,i,dstsd->addeff3[type]);
+ status_change_start(src,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[type],7),0);
+ }
}
}
return 0;
@@ -1379,7 +1122,7 @@ int skill_blown( struct block_list *src, struct block_list *target,int count)
{
int dx=0,dy=0,nx,ny;
int x=target->x,y=target->y;
- int ret,prev_state=MS_IDLE;
+ int dir,ret,prev_state=MS_IDLE;
int moveblock;
struct map_session_data *sd=NULL;
struct mob_data *md=NULL;
@@ -1390,25 +1133,24 @@ int skill_blown( struct block_list *src, struct block_list *target,int count)
nullpo_retr(0, target);
if(target->type==BL_PC){
- nullpo_retr(0, sd=(struct map_session_data *)target);
+ sd=(struct map_session_data *)target;
}else if(target->type==BL_MOB){
- nullpo_retr(0, md=(struct mob_data *)target);
+ md=(struct mob_data *)target;
}else if(target->type==BL_PET){
- nullpo_retr(0, pd=(struct pet_data *)target);
+ pd=(struct pet_data *)target;
}else if(target->type==BL_SKILL){
- nullpo_retr(0, su=(struct skill_unit *)target);
+ su=(struct skill_unit *)target;
}else return 0;
- if(!(count&0x10000 && (sd||md||pd||su))){ /* Žw’è‚È‚µ‚È‚çˆÊ’u?ŒW‚©‚ç•ûŒü‚ð‹‚ß‚é */
- dx=target->x-src->x; dx=(dx>0)?1:((dx<0)?-1: 0);
- dy=target->y-src->y; dy=(dy>0)?1:((dy<0)?-1: 0);
- }
- if(dx==0 && dy==0){
- int dir=battle_get_dir(target);
- if(dir>=0 && dir<8){
- dx=-dirx[dir];
- dy=-diry[dir];
- }
+ if (count&0xf00000)
+ dir = (count>>20)&0xf;
+ else if (count&0x10000 || (target->x==src->x && target->y==src->y))
+ dir = status_get_dir(target);
+ else
+ dir = map_calc_dir(target,src->x,src->y);
+ if (dir>=0 && dir<8){
+ dx = -dirx[dir];
+ dy = -diry[dir];
}
ret=path_blownpos(target->m,x,y,dx,dy,count&0xffff);
@@ -1456,18 +1198,13 @@ int skill_blown( struct block_list *src, struct block_list *target,int count)
if(su){
skill_unit_move_unit_group(su->group,target->m,dx,dy);
}else{
-// struct status_change *sc_data=battle_get_sc_data(target);
- if(moveblock) map_delblock(target);
- target->x=nx;
- target->y=ny;
- if(moveblock) map_addblock(target);
-/*ƒ_ƒ“ƒX’†‚ɃGƒtƒFƒNƒg‚͈ړ®‚µ‚È‚¢‚炵‚¢
- if(sc_data && sc_data[SC_DANCING].timer!=-1){ //?Û‚ªƒ_ƒ“ƒX’†‚Ȃ̂ŃGƒtƒFƒNƒg‚àˆÚ“®
- struct skill_unit_group *sg=(struct skill_unit_group *)sc_data[SC_DANCING].val2;
- if(sg)
- skill_unit_move_unit_group(sg,target->m,dx,dy);
- }
-*/
+ int tick = gettick();
+ skill_unit_move(target,tick,0);
+ if(moveblock) map_delblock(target);
+ target->x=nx;
+ target->y=ny;
+ if(moveblock) map_addblock(target);
+ skill_unit_move(target,tick,1);
}
if(sd) { /* ?–Ê?‚É“ü‚Á‚Ä‚«‚½‚̂ŕ\ަ */
@@ -1486,8 +1223,6 @@ int skill_blown( struct block_list *src, struct block_list *target,int count)
pd->state.state = prev_state;
}
- skill_unit_move(target,gettick(),(count&0xffff)+7); /* ƒXƒLƒ‹ƒ†ƒjƒbƒg‚Ì”»’è */
-
return 0;
}
@@ -1510,15 +1245,16 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
struct Damage dmg;
struct status_change *sc_data;
int type,lv,damage;
+ static int tmpdmg = 0;
- if(skilllv <= 0) return 0;
+ if(skillid > 0 && skilllv <= 0) return 0;
rdamage = 0;
nullpo_retr(0, src);
nullpo_retr(0, dsrc);
nullpo_retr(0, bl);
- sc_data = battle_get_sc_data(bl);
+ sc_data = status_get_sc_data(bl);
//‰½‚à‚µ‚È‚¢”»’肱‚±‚©‚ç
if(dsrc->m != bl->m) //?Û‚ª“¯‚¶ƒ}ƒbƒv‚É‚¢‚È‚¯‚ê‚Ή½‚à‚µ‚È‚¢
@@ -1527,11 +1263,11 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
return 0;
if(src->type == BL_PC && pc_isdead((struct map_session_data *)src)) //pŽÒH‚ªPC‚Å‚·‚łɎ€‚ñ‚Å‚¢‚½‚牽‚à‚µ‚È‚¢
return 0;
- if(dsrc->type == BL_PC && pc_isdead((struct map_session_data *)dsrc)) //pŽÒH‚ªPC‚Å‚·‚łɎ€‚ñ‚Å‚¢‚½‚牽‚à‚µ‚È‚¢
+ if(src != dsrc && dsrc->type == BL_PC && pc_isdead((struct map_session_data *)dsrc)) //pŽÒH‚ªPC‚Å‚·‚łɎ€‚ñ‚Å‚¢‚½‚牽‚à‚µ‚È‚¢
return 0;
if(bl->type == BL_PC && pc_isdead((struct map_session_data *)bl)) //?Û‚ªPC‚Å‚·‚łɎ€‚ñ‚Å‚¢‚½‚牽‚à‚µ‚È‚¢
return 0;
- if(bl->type == BL_PC && skillnotok(skillid, (struct map_session_data *) bl))
+ if(bl->type == BL_PC && skillnotok(skillid, (struct map_session_data *)bl))
return 0; // [MouseJstr]
if(sc_data && sc_data[SC_HIDING].timer != -1) { //ƒnƒCƒfƒBƒ“ƒO?‘Ô‚Å
if(skill_get_pl(skillid) != 2) //ƒXƒLƒ‹‚Ì?«‚ª’n?«‚łȂ¯‚ê‚Ή½‚à‚µ‚È‚¢
@@ -1562,27 +1298,30 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
if(attack_type&BF_MAGIC && sc_data && sc_data[SC_MAGICROD].timer != -1 && src == dsrc) { //–‚–@U?‚Ń}ƒWƒbƒNƒƒbƒh?‘Ô‚Åsrc=dsrc‚È‚ç
dmg.damage = dmg.damage2 = 0; //ƒ_ƒ?ƒW0
if(bl->type == BL_PC) { //?Û‚ªPC‚Ìê‡
- int sp = skill_get_sp(skillid,skilllv); //Žg—p‚³‚ꂽƒXƒLƒ‹‚ÌSP‚ð‹z?
- sp = sp * sc_data[SC_MAGICROD].val2 / 100; //‹z?—¦ŒvŽZ
- if(skillid == WZ_WATERBALL && skilllv > 1) //ƒEƒH?ƒ^?ƒ{?ƒ‹Lv1ˆÈã
- sp = sp/((skilllv|1)*(skilllv|1)); //‚³‚ç‚ÉŒvŽZH
- if(sp > 0x7fff) sp = 0x7fff; //SP‘½‚·‚¬‚Ìꇂ͗˜_Å‘å’l
- else if(sp < 1) sp = 1; //1ˆÈ‰º‚ÌꇂÍ1
- if(((struct map_session_data *)bl)->status.sp + sp > ((struct map_session_data *)bl)->status.max_sp) { //‰ñ•œSP+Œ»Ý‚ÌSP‚ªMSP‚æ‚è‘å‚«‚¢ê‡
- sp = ((struct map_session_data *)bl)->status.max_sp - ((struct map_session_data *)bl)->status.sp; //SP‚ðMSP-Œ»ÝSP‚É‚·‚é
- ((struct map_session_data *)bl)->status.sp = ((struct map_session_data *)bl)->status.max_sp; //Œ»Ý‚ÌSP‚ÉMSP‚ð‘ã“ü
- }
- else //‰ñ•œSP+Œ»Ý‚ÌSP‚ªMSP‚æ‚謂³‚¢ê‡‚͉ñ•œSP‚ð‰ÁŽZ
- ((struct map_session_data *)bl)->status.sp += sp;
- clif_heal(((struct map_session_data *)bl)->fd,SP_SP,sp); //SP‰ñ•œƒGƒtƒFƒNƒg‚Ì•\ަ
- ((struct map_session_data *)bl)->canact_tick = tick + skill_delayfix(bl, skill_get_delay(SA_MAGICROD,sc_data[SC_MAGICROD].val1)); //
+ struct map_session_data *sd = (struct map_session_data *)bl;
+ if (sd) {
+ int sp = skill_get_sp(skillid,skilllv); //Žg—p‚³‚ꂽƒXƒLƒ‹‚ÌSP‚ð‹z?
+ sp = sp * sc_data[SC_MAGICROD].val2 / 100; //‹z?—¦ŒvŽZ
+ if(skillid == WZ_WATERBALL && skilllv > 1) //ƒEƒH?ƒ^?ƒ{?ƒ‹Lv1ˆÈã
+ sp = sp/((skilllv|1)*(skilllv|1)); //‚³‚ç‚ÉŒvŽZH
+ if(sp > 0x7fff) sp = 0x7fff; //SP‘½‚·‚¬‚Ìꇂ͗˜_Å‘å’l
+ else if(sp < 1) sp = 1; //1ˆÈ‰º‚ÌꇂÍ1
+ if(sd->status.sp + sp > sd->status.max_sp) { //‰ñ•œSP+Œ»Ý‚ÌSP‚ªMSP‚æ‚è‘å‚«‚¢ê‡
+ sp = sd->status.max_sp - sd->status.sp; //SP‚ðMSP-Œ»ÝSP‚É‚·‚é
+ sd->status.sp = sd->status.max_sp; //Œ»Ý‚ÌSP‚ÉMSP‚ð‘ã“ü
+ }
+ else //‰ñ•œSP+Œ»Ý‚ÌSP‚ªMSP‚æ‚謂³‚¢ê‡‚͉ñ•œSP‚ð‰ÁŽZ
+ sd->status.sp += sp;
+ clif_heal(sd->fd,SP_SP,sp); //SP‰ñ•œƒGƒtƒFƒNƒg‚Ì•\ަ
+ sd->canact_tick = tick + skill_delayfix(bl, skill_get_delay(SA_MAGICROD,sc_data[SC_MAGICROD].val1)); //
+ }
}
clif_skill_nodamage(bl,bl,SA_MAGICROD,sc_data[SC_MAGICROD].val1,1); //ƒ}ƒWƒbƒNƒƒbƒhƒGƒtƒFƒNƒg‚ð•\ަ
}
//ƒ}ƒWƒbƒNƒƒbƒh?—‚±‚±‚Ü‚Å
if(src->type==BL_PET) { // [Valaris]
- dmg.damage=battle_attr_fix(skilllv, skill_get_pl(skillid), battle_get_element(bl) );
+ dmg.damage=battle_attr_fix(skilllv, skill_get_pl(skillid), status_get_element(bl) );
dmg.damage2=0;
}
@@ -1597,7 +1336,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
if(damage <= 0 || damage < dmg.div_) //‚«”ò‚΂µ”»’èH¦
dmg.blewcount = 0;
- if(skillid == CR_GRANDCROSS) {//ƒOƒ‰ƒ“ƒhƒNƒƒX
+ if(skillid == CR_GRANDCROSS||skillid == NPC_DARKGRANDCROSS) {//ƒOƒ‰ƒ“ƒhƒNƒƒX
if(battle_config.gx_disptype) dsrc = src; // “Gƒ_ƒ?ƒW”’•¶Žš•\ަ
if( src == bl) type = 4; // ”½“®‚̓_ƒ?ƒWƒ‚?ƒVƒ‡ƒ“‚È‚µ
}
@@ -1608,12 +1347,12 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
nullpo_retr(0, sd);
//˜A‘Ŷ(MO_CHAINCOMBO)‚±‚±‚©‚ç
if(skillid == MO_CHAINCOMBO) {
- int delay = 1000 - 4 * battle_get_agi(src) - 2 * battle_get_dex(src); //Šî–{ƒfƒBƒŒƒC‚ÌŒvŽZ
- if(damage < battle_get_hp(bl)) { //ƒ_ƒ?ƒW‚ª?Û‚ÌHP‚æ‚謂³‚¢ê‡
+ int delay = 1000 - 4 * status_get_agi(src) - 2 * status_get_dex(src); //Šî–{ƒfƒBƒŒƒC‚ÌŒvŽZ
+ if(damage < status_get_hp(bl)) { //ƒ_ƒ?ƒW‚ª?Û‚ÌHP‚æ‚謂³‚¢ê‡
if(pc_checkskill(sd, MO_COMBOFINISH) > 0 && sd->spiritball > 0) //–Ò—´Œ(MO_COMBOFINISH)Žæ“¾•?‹…•ÛŽŽž‚Í+300ms
delay += 300 * battle_config.combo_delay_rate /100; //’ljÁƒfƒBƒŒƒC‚ðconf‚É‚æ‚è’²®
- skill_status_change_start(src,SC_COMBO,MO_CHAINCOMBO,skilllv,0,0,delay,0); //ƒRƒ“ƒ{?‘Ô‚É
+ status_change_start(src,SC_COMBO,MO_CHAINCOMBO,skilllv,0,0,delay,0); //ƒRƒ“ƒ{?‘Ô‚É
}
sd->attackabletime = sd->canmove_tick = tick + delay;
clif_combo_delay(src,delay); //ƒRƒ“ƒ{ƒfƒBƒŒƒCƒpƒPƒbƒg‚Ì‘—M
@@ -1621,8 +1360,8 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
//˜A‘Ŷ(MO_CHAINCOMBO)‚±‚±‚Ü‚Å
//–Ò—´Œ(MO_COMBOFINISH)‚±‚±‚©‚ç
else if(skillid == MO_COMBOFINISH) {
- int delay = 700 - 4 * battle_get_agi(src) - 2 * battle_get_dex(src);
- if(damage < battle_get_hp(bl)) {
+ int delay = 700 - 4 * status_get_agi(src) - 2 * status_get_dex(src);
+ if(damage < status_get_hp(bl)) {
//ˆ¢C—…”e™€Œ(MO_EXTREMITYFIST)Žæ“¾•?‹…4ŒÂ•ÛŽ•”š—ô”g“®(MO_EXPLOSIONSPIRITS)?‘ÔŽž‚Í+300ms
//•šŒÕŒ(CH_TIGERFIST)Žæ“¾Žž‚à+300ms
if((pc_checkskill(sd, MO_EXTREMITYFIST) > 0 && sd->spiritball >= 4 && sd->sc_data[SC_EXPLOSIONSPIRITS].timer != -1) ||
@@ -1630,7 +1369,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
(pc_checkskill(sd, CH_CHAINCRUSH) > 0 && sd->spiritball > 1))
delay += 300 * battle_config.combo_delay_rate /100; //’ljÁƒfƒBƒŒƒC‚ðconf‚É‚æ‚è’²®
- skill_status_change_start(src,SC_COMBO,MO_COMBOFINISH,skilllv,0,0,delay,0); //ƒRƒ“ƒ{?‘Ô‚É
+ status_change_start(src,SC_COMBO,MO_COMBOFINISH,skilllv,0,0,delay,0); //ƒRƒ“ƒ{?‘Ô‚É
}
sd->attackabletime = sd->canmove_tick = tick + delay;
clif_combo_delay(src,delay); //ƒRƒ“ƒ{ƒfƒBƒŒƒCƒpƒPƒbƒg‚Ì‘—M
@@ -1638,12 +1377,12 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
//–Ò—´Œ(MO_COMBOFINISH)‚±‚±‚Ü‚Å
//•šŒÕŒ(CH_TIGERFIST)‚±‚±‚©‚ç
else if(skillid == CH_TIGERFIST) {
- int delay = 1000 - 4 * battle_get_agi(src) - 2 * battle_get_dex(src);
- if(damage < battle_get_hp(bl)) {
+ int delay = 1000 - 4 * status_get_agi(src) - 2 * status_get_dex(src);
+ if(damage < status_get_hp(bl)) {
if(pc_checkskill(sd, CH_CHAINCRUSH) > 0) //˜A’Œ•ö?(CH_CHAINCRUSH)Žæ“¾Žž‚Í+300ms
delay += 300 * battle_config.combo_delay_rate /100; //’ljÁƒfƒBƒŒƒC‚ðconf‚É‚æ‚è’²®
- skill_status_change_start(src,SC_COMBO,CH_TIGERFIST,skilllv,0,0,delay,0); //ƒRƒ“ƒ{?‘Ô‚É
+ status_change_start(src,SC_COMBO,CH_TIGERFIST,skilllv,0,0,delay,0); //ƒRƒ“ƒ{?‘Ô‚É
}
sd->attackabletime = sd->canmove_tick = tick + delay;
clif_combo_delay(src,delay); //ƒRƒ“ƒ{ƒfƒBƒŒƒCƒpƒPƒbƒg‚Ì‘—M
@@ -1651,13 +1390,13 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
//•šŒÕŒ(CH_TIGERFIST)‚±‚±‚Ü‚Å
//˜A’Œ•ö?(CH_CHAINCRUSH)‚±‚±‚©‚ç
else if(skillid == CH_CHAINCRUSH) {
- int delay = 1000 - 4 * battle_get_agi(src) - 2 * battle_get_dex(src);
- if(damage < battle_get_hp(bl)) {
+ int delay = 1000 - 4 * status_get_agi(src) - 2 * status_get_dex(src);
+ if(damage < status_get_hp(bl)) {
//ˆ¢C—…”e™€Œ(MO_EXTREMITYFIST)Žæ“¾•?‹…4ŒÂ•ÛŽ•”š—ô”g“®(MO_EXPLOSIONSPIRITS)?‘ÔŽž‚Í+300ms
if(pc_checkskill(sd, MO_EXTREMITYFIST) > 0 && sd->spiritball >= 4 && sd->sc_data[SC_EXPLOSIONSPIRITS].timer != -1)
delay += 300 * battle_config.combo_delay_rate /100; //’ljÁƒfƒBƒŒƒC‚ðconf‚É‚æ‚è’²®
- skill_status_change_start(src,SC_COMBO,CH_CHAINCRUSH,skilllv,0,0,delay,0); //ƒRƒ“ƒ{?‘Ô‚É
+ status_change_start(src,SC_COMBO,CH_CHAINCRUSH,skilllv,0,0,delay,0); //ƒRƒ“ƒ{?‘Ô‚É
}
sd->attackabletime = sd->canmove_tick = tick + delay;
clif_combo_delay(src,delay); //ƒRƒ“ƒ{ƒfƒBƒŒƒCƒpƒPƒbƒg‚Ì‘—M
@@ -1708,23 +1447,32 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
//•ŠíƒXƒLƒ‹H‚±‚±‚Ü‚Å
switch(skillid){
- case WZ_SIGHTRASHER:
- clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, (lv!=0)?lv:skilllv, 5);
- break;
case AS_SPLASHER:
clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, -1, 5);
break;
+ case ASC_BREAKER: // [celest]
+ if (attack_type&BF_MAGIC) { // only display damage for the 2nd attack
+ if (damage + tmpdmg != 0) // if both attacks missed, do not display a 2nd 'miss'
+ clif_skill_damage(dsrc, bl, tick, dmg.amotion, dmg.dmotion, damage+tmpdmg, dmg.div_, skillid, skilllv, type);
+ tmpdmg = 0; // clear the temporary damage
+ } else {
+ if (damage == 0) // if weapon attack missed, display the 'miss'
+ clif_skill_damage(dsrc, bl, tick, dmg.amotion, dmg.dmotion, 0, dmg.div_, skillid, skilllv, type);
+ tmpdmg = damage; // store the temporary weapon damage
+ }
+ break;
case NPC_SELFDESTRUCTION:
case NPC_SELFDESTRUCTION2:
break;
+ case SN_SHARPSHOOTING:
+ clif_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,0,0,0);
+ break;
default:
clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, (lv!=0)?lv:skilllv, (skillid==0)? 5:type );
}
- if(dmg.blewcount > 0 && !map[src->m].flag.gvg) { /* ‚«”ò‚΂µ?—‚Æ‚»‚̃pƒPƒbƒg */
- if(skillid == WZ_SIGHTRASHER)
- skill_blown(src,bl,dmg.blewcount);
- else
- skill_blown(dsrc,bl,dmg.blewcount);
+ /* ‚«”ò‚΂µˆ—‚Æ‚»‚̃pƒPƒbƒg */
+ if (dmg.blewcount > 0 && bl->type!=BL_SKILL && !map[src->m].flag.gvg) {
+ skill_blown(dsrc,bl,dmg.blewcount);
if(bl->type == BL_MOB)
clif_fixmobpos((struct mob_data *)bl);
else if(bl->type == BL_PET)
@@ -1735,28 +1483,31 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
map_freeblock_lock();
/* ?ۂɃ_ƒ?ƒW?—‚ðs‚¤ */
- if(skillid != KN_BOWLINGBASH || flag)
- battle_damage(src,bl,damage,0);
- if(skillid == RG_INTIMIDATE && damage > 0 && !(battle_get_mode(bl)&0x20) && !map[src->m].flag.gvg ) {
- int s_lv = battle_get_lv(src),t_lv = battle_get_lv(bl);
+ if (skillid || flag) {
+ if (attack_type&BF_WEAPON)
+ battle_delay_damage(tick+dmg.amotion,src,bl,damage,0);
+ else
+ battle_damage(src,bl,damage,0);
+ }
+ if(skillid == RG_INTIMIDATE && damage > 0 && !(status_get_mode(bl)&0x20) && !map[src->m].flag.gvg ) {
+ int s_lv = status_get_lv(src),t_lv = status_get_lv(bl);
int rate = 50 + skilllv * 5;
rate = rate + (s_lv - t_lv);
if(rand()%100 < rate)
skill_addtimerskill(src,tick + 800,bl->id,0,0,skillid,skilllv,0,flag);
}
- if(damage > 0 && dmg.flag&BF_SKILL && bl->type==BL_PC && pc_checkskill((struct map_session_data *)bl,RG_PLAGIARISM) && sc_data[SC_PRESERVE].timer != -1){
+ if(damage > 0 && dmg.flag&BF_SKILL && bl->type==BL_PC && pc_checkskill((struct map_session_data *)bl,RG_PLAGIARISM) && sc_data[SC_PRESERVE].timer == -1){
struct map_session_data *tsd = (struct map_session_data *)bl;
nullpo_retr(0, tsd);
- if(!tsd->status.skill[skillid].id && !tsd->status.skill[skillid].id
- && !(skillid > NPC_PIERCINGATT && skillid < NPC_SUMMONMONSTER) ){
+ if(!tsd->status.skill[skillid].id && !tsd->status.skill[skillid].lv
+ && !(skillid > NPC_PIERCINGATT && skillid < NPC_SUMMONMONSTER)
+ && !(skillid > NPC_SELFDESTRUCTION2 && skillid < NPC_UNDEADATTACK)){
//?‚É?‚ñ‚Å‚¢‚éƒXƒLƒ‹‚ª‚ ‚ê‚ΊY?ƒXƒLƒ‹‚ðÁ‚·
- if (tsd->cloneskill_id && tsd->cloneskill_lv && tsd->status.skill[tsd->cloneskill_id].flag==13){
+ if (tsd->cloneskill_id && tsd->status.skill[tsd->cloneskill_id].flag==13){
tsd->status.skill[tsd->cloneskill_id].id=0;
- tsd->status.skill[tsd->cloneskill_id].lv=0;
tsd->status.skill[tsd->cloneskill_id].flag=0;
}
tsd->cloneskill_id=skillid;
- tsd->cloneskill_lv=skilllv;
tsd->status.skill[skillid].id=skillid;
tsd->status.skill[skillid].lv=(pc_checkskill(tsd,RG_PLAGIARISM) > skill_get_max(skillid))?
skill_get_max(skillid):pc_checkskill(tsd,RG_PLAGIARISM);
@@ -1766,13 +1517,11 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
}
/* ƒ_ƒ?ƒW‚ª‚ ‚é‚È‚ç’ljÁ?‰Ê”»’è */
if(bl->prev != NULL){
- struct map_session_data *sd = (struct map_session_data *)bl;
- nullpo_retr(0, sd);
- if( bl->type != BL_PC || (sd && !pc_isdead(sd)) ) {
- if(damage > 0)
- skill_additional_effect(src,bl,skillid,skilllv,attack_type,tick);
- if(bl->type==BL_MOB && src!=bl) /* ƒXƒLƒ‹Žg—p?Œ‚ÌMOBƒXƒLƒ‹ */
- {
+ if(!status_isdead(bl)) {
+ if(damage > 0)
+ skill_additional_effect(src,bl,skillid,skilllv,attack_type,tick);
+ if(bl->type==BL_MOB && src!=bl) /* ƒXƒLƒ‹Žg—p?Œ‚ÌMOBƒXƒLƒ‹ */
+ {
struct mob_data *md=(struct mob_data *)bl;
nullpo_retr(0, md);
if(battle_config.mob_changetarget_byskill == 1)
@@ -1814,16 +1563,23 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
if(sd->sp_drain_rate_ > 0 && sp < 1) sp = 1;
else if(sd->sp_drain_rate_ < 0 && sp > -1) sp = -1;
}
- if(hp || sp) pc_heal(sd,hp,sp);
+ if(hp || sp)
+ pc_heal(sd,hp,sp);
+ if (sd->sp_drain_type && bl->type == BL_PC)
+ battle_heal(NULL,bl,0,-sp,0);
}
- if((skillid != KN_BOWLINGBASH || flag) && rdamage > 0)
- battle_damage(bl,src,rdamage,0);
+ if ((skillid || flag) && rdamage>0) {
+ if (attack_type&BF_WEAPON)
+ battle_delay_damage(tick+dmg.amotion,bl,src,rdamage,0);
+ else
+ battle_damage(bl,src,rdamage,0);
+ }
if(attack_type&BF_WEAPON && sc_data && sc_data[SC_AUTOCOUNTER].timer != -1 && sc_data[SC_AUTOCOUNTER].val4 > 0) {
if(sc_data[SC_AUTOCOUNTER].val3 == dsrc->id)
battle_weapon_attack(bl,dsrc,tick,0x8000|sc_data[SC_AUTOCOUNTER].val1);
- skill_status_change_end(bl,SC_AUTOCOUNTER,-1);
+ status_change_end(bl,SC_AUTOCOUNTER,-1);
}
map_freeblock_unlock();
@@ -1870,9 +1626,8 @@ int skill_area_sub( struct block_list *bl,va_list ap )
static int skill_check_unit_range_sub( struct block_list *bl,va_list ap )
{
struct skill_unit *unit;
- int *c,x,y,range,sx[4],sy[4];
- int t_range,tx[4],ty[4];
- int i,r_flag,skillid;
+ int *c;
+ int skillid,unit_id;
nullpo_retr(0, bl);
nullpo_retr(0, ap);
@@ -1885,57 +1640,46 @@ static int skill_check_unit_range_sub( struct block_list *bl,va_list ap )
if(!unit->alive)
return 0;
- x = va_arg(ap,int);
- y = va_arg(ap,int);
- range = va_arg(ap,int);
skillid = va_arg(ap,int);
+ unit_id = unit->group->unit_id;
- if(skillid == MG_SAFETYWALL || skillid == AL_PNEUMA) {
- if(unit->group->unit_id != 0x7e && unit->group->unit_id != 0x85)
+ if (skillid==MG_SAFETYWALL || skillid==AL_PNEUMA) {
+ if(unit_id != 0x7e && unit_id != 0x85)
return 0;
- }
- else if(skillid == AL_WARP) {
- if((unit->group->unit_id < 0x8f || unit->group->unit_id > 0x99) && unit->group->unit_id != 0x92)
+ } else if (skillid==AL_WARP) {
+ if ((unit_id<0x8f || unit_id>0x99) && unit_id!=0x92)
return 0;
- }
- else if((skillid >= HT_SKIDTRAP && skillid <= HT_CLAYMORETRAP) || skillid == HT_TALKIEBOX) {
- if((unit->group->unit_id < 0x8f || unit->group->unit_id > 0x99) && unit->group->unit_id != 0x92)
+ } else if ((skillid>=HT_SKIDTRAP && skillid<=HT_CLAYMORETRAP) || skillid==HT_TALKIEBOX) {
+ if ((unit_id<0x8f || unit_id>0x99) && unit_id!=0x92)
return 0;
- }
- else if(skillid == WZ_FIREPILLAR) {
- if(unit->group->unit_id != 0x87)
+ } else if (skillid==WZ_FIREPILLAR) {
+ if (unit_id!=0x87)
return 0;
- }
- else return 0;
- t_range=(unit->range!=0)? unit->range:unit->group->range;
- tx[0] = tx[3] = unit->bl.x - t_range;
- tx[1] = tx[2] = unit->bl.x + t_range;
- ty[0] = ty[1] = unit->bl.y - t_range;
- ty[2] = ty[3] = unit->bl.y + t_range;
- sx[0] = sx[3] = x - range;
- sx[1] = sx[2] = x + range;
- sy[0] = sy[1] = y - range;
- sy[2] = sy[3] = y + range;
- for(i=r_flag=0;i<4;i++) {
- if(sx[i] >= tx[0] && sx[i] <= tx[1] && sy[i] >= ty[0] && sy[i] <= ty[2]) {
- r_flag = 1;
- break;
- }
- if(tx[i] >= sx[0] && tx[i] <= sx[1] && ty[i] >= sy[0] && ty[i] <= sy[2]) {
- r_flag = 1;
- break;
- }
- }
- if(r_flag) (*c)++;
+ } else if (skillid==HP_BASILICA) {
+ if ((unit_id<0x8f || unit_id>0x99) && unit_id!=0x92 && unit_id!=0x83)
+ return 0;
+ } else
+ return 0;
+
+ (*c)++;
return 0;
}
-int skill_check_unit_range(int m,int x,int y,int range,int skillid)
+int skill_check_unit_range(int m,int x,int y,int skillid,int skilllv)
{
int c = 0;
+ int range = skill_get_unit_range(skillid);
+ int layout_type = skill_get_unit_layout_type(skillid,skilllv);
+ if (layout_type==-1 || layout_type>MAX_SQUARE_LAYOUT) {
+ printf("skill_check_unit_range: unsupported layout type %d for skill %d\n",layout_type,skillid);
+ return 0;
+ }
- map_foreachinarea(skill_check_unit_range_sub,m,x-10,y-10,x+10,y+10,BL_SKILL,&c,x,y,range,skillid);
+ // ‚Ƃ肠‚¦‚¸³•ûŒ`‚̃†ƒjƒbƒgƒŒƒCƒAƒEƒg‚̂ݑΉž
+ range += layout_type;
+ map_foreachinarea(skill_check_unit_range_sub,m,
+ x-range,y-range,x+range,y+range,BL_SKILL,&c,skillid);
return c;
}
@@ -1943,6 +1687,8 @@ int skill_check_unit_range(int m,int x,int y,int range,int skillid)
static int skill_check_unit_range2_sub( struct block_list *bl,va_list ap )
{
int *c;
+ int skillid;
+
nullpo_retr(0, bl);
nullpo_retr(0, ap);
@@ -1954,32 +1700,117 @@ static int skill_check_unit_range2_sub( struct block_list *bl,va_list ap )
if(bl->type == BL_PC && pc_isdead((struct map_session_data *)bl))
return 0;
+ skillid = va_arg(ap,int);
+ if (skillid==HP_BASILICA && bl->type==BL_PC)
+ return 0;
+
(*c)++;
return 0;
}
-int skill_check_unit_range2(int m,int x,int y,int range)
+int skill_check_unit_range2(struct block_list *bl, int m,int x,int y,int skillid, int skilllv)
{
- int c = 0;
+ int c = 0, range, type;
+
+ switch (skillid) { // to be expanded later
+ case WZ_ICEWALL:
+ range = 2;
+ break;
+ default:
+ {
+ int layout_type = skill_get_unit_layout_type(skillid,skilllv);
+ if (layout_type==-1 || layout_type>MAX_SQUARE_LAYOUT) {
+ printf("skill_check_unit_range2: unsupported layout type %d for skill %d\n",layout_type,skillid);
+ return 0;
+ }
+ // ‚Ƃ肠‚¦‚¸³•ûŒ`‚̃†ƒjƒbƒgƒŒƒCƒAƒEƒg‚̂ݑΉž
+ range = skill_get_unit_range(skillid) + layout_type;
+ }
+ break;
+ }
- map_foreachinarea(skill_check_unit_range2_sub,m,x-range,y-range,x+range,y+range,0,&c);
+ // if the caster is a monster/NPC, only check for players
+ // otherwise just check everything
+ if (bl->type == BL_PC)
+ type = 0;
+ else type = BL_PC;
+
+ map_foreachinarea(skill_check_unit_range2_sub, m,
+ x - range, y - range, x + range, y + range,
+ type, &c, skillid);
return c;
}
+int skill_guildaura_sub (struct block_list *bl,va_list ap)
+{
+ struct map_session_data *sd;
+ struct guild *g;
+ int gid, id;
+ int flag = 0;
+
+ nullpo_retr(0, sd=(struct map_session_data *)bl);
+
+ nullpo_retr(0, ap);
+ id = va_arg(ap,int);
+ gid = va_arg(ap,int);
+ if (sd->status.guild_id != gid)
+ return 0;
+
+ g = va_arg(ap,struct guild *);
+ if (guild_checkskill(g, GD_LEADERSHIP)>0) flag |= 1<<0;
+ if (guild_checkskill(g, GD_GLORYWOUNDS)>0) flag |= 1<<1;
+ if (guild_checkskill(g, GD_SOULCOLD)>0) flag |= 1<<2;
+ if (guild_checkskill(g, GD_HAWKEYES)>0) flag |= 1<<3;
+ if (guild_checkskill(g, GD_CHARISMA)>0) flag |= 1<<4;
+
+ if (flag > 0) {
+ if (sd->sc_count && sd->sc_data[SC_GUILDAURA].timer != -1) {
+ if (sd->sc_data[SC_GUILDAURA].val4 != flag) {
+ sd->sc_data[SC_GUILDAURA].val4 = flag;
+ status_calc_pc (sd, 0);
+ }
+ return 0;
+ }
+ status_change_start(&sd->bl, SC_GUILDAURA,1,id,0,flag,0,0 );
+ }
+
+ return 0;
+}
+
/*=========================================================================
* ”Í?ƒXƒLƒ‹Žg—p?—¬•ª‚¯‚±‚±‚©‚ç
*/
/* ?Û‚Ì?‚ðƒJƒEƒ“ƒg‚·‚éBiskill_area_temp[0]‚ð‰Šú‰»‚µ‚Ä‚¨‚­‚±‚Æj */
int skill_area_sub_count(struct block_list *src,struct block_list *target,int skillid,int skilllv,unsigned int tick,int flag)
{
- if(skilllv <= 0) return 0;
if(skill_area_temp[0] < 0xffff)
skill_area_temp[0]++;
return 0;
}
+int skill_count_water(struct block_list *src,int range)
+{
+ int i,x,y,cnt = 0,size = range*2+1;
+ struct skill_unit *unit;
+
+ for (i=0;i<size*size;i++) {
+ x = src->x+(i%size-range);
+ y = src->y+(i/size-range);
+ if (map_getcell(src->m,x,y,CELL_CHKWATER)) {
+ cnt++;
+ continue;
+ }
+ unit = map_find_skill_unit_oncell(src,x,y,SA_DELUGE,NULL);
+ if (unit) {
+ cnt++;
+ skill_delunit(unit);
+ }
+ }
+ return cnt;
+}
+
/*==========================================
*
*------------------------------------------
@@ -2017,6 +1848,10 @@ static int skill_timerskill(int tid, unsigned int tick, int id,int data )
nullpo_retr(0, skl);
skl->timer = -1;
+ if (sd) {
+ sd->timerskill_count--;
+ }
+
if(skl->target_id) {
struct block_list tbl;
target = map_id2bl(skl->target_id);
@@ -2045,13 +1880,13 @@ static int skill_timerskill(int tid, unsigned int tick, int id,int data )
break;
case RG_INTIMIDATE:
if(sd && !map[src->m].flag.noteleport) {
- int x,y,i,j,c;
+ int x,y,i,j;
pc_randomwarp(sd,3);
for(i=0;i<16;i++) {
j = rand()%8;
x = sd->bl.x + dirx[j];
y = sd->bl.y + diry[j];
- if((c=map_getcell(sd->bl.m,x,y)) != 1 && c != 5)
+ if(map_getcell(sd->bl.m,x,y,CELL_CHKPASS))
break;
}
if(i >= 16) {
@@ -2066,13 +1901,13 @@ static int skill_timerskill(int tid, unsigned int tick, int id,int data )
}
}
else if(md && !map[src->m].flag.monster_noteleport) {
- int x,y,i,j,c;
+ int x,y,i,j;
mob_warp(md,-1,-1,-1,3);
for(i=0;i<16;i++) {
j = rand()%8;
x = md->bl.x + dirx[j];
y = md->bl.y + diry[j];
- if((c=map_getcell(md->bl.m,x,y)) != 1 && c != 5)
+ if(map_getcell(md->bl.m,x,y,CELL_CHKPASS))
break;
}
if(i >= 16) {
@@ -2090,11 +1925,26 @@ static int skill_timerskill(int tid, unsigned int tick, int id,int data )
case BA_FROSTJOKE: /* Ц‚¢ƒWƒ‡?ƒN */
case DC_SCREAM: /* ƒXƒNƒŠ?ƒ€ */
- range=15; //Ž‹ŠE‘S?
+ range=battle_config.area_size; //Ž‹ŠE‘S?
map_foreachinarea(skill_frostjoke_scream,src->m,src->x-range,src->y-range,
src->x+range,src->y+range,0,src,skl->skill_id,skl->skill_lv,tick);
break;
+ case WZ_WATERBALL:
+ if (skl->type>1) {
+ skl->timer = 0; // skill_addtimerskill‚ÅŽg—p‚³‚ê‚È‚¢‚悤‚É
+ skill_addtimerskill(src,tick+150,target->id,0,0,skl->skill_id,skl->skill_lv,skl->type-1,skl->flag);
+ skl->timer = -1;
+ }
+ skill_attack(BF_MAGIC,src,src,target,skl->skill_id,skl->skill_lv,tick,skl->flag);
+ if (skl->type <= 1) { // partial fix: it still doesn't end if the target dies
+ // should put outside of the switch, but since this is the only
+ // mage targetted spell for now,
+ struct status_change *sc_data = status_get_sc_data(src);
+ if(sc_data && sc_data[SC_MAGICPOWER].timer != -1) //ƒ}ƒWƒbƒNƒpƒ?‚Ì?‰ÊI—¹
+ status_change_end(src,SC_MAGICPOWER,-1);
+ }
+ break;
default:
skill_attack(skl->type,src,src,target,skl->skill_id,skl->skill_lv,tick,skl->flag);
break;
@@ -2143,6 +1993,7 @@ int skill_addtimerskill(struct block_list *src,unsigned int tick,int target,int
sd->skilltimerskill[i].y = y;
sd->skilltimerskill[i].type = type;
sd->skilltimerskill[i].flag = flag;
+ sd->timerskill_count++;
return 0;
}
@@ -2207,10 +2058,15 @@ int skill_cleartimerskill(struct block_list *src)
if(src->type == BL_PC) {
struct map_session_data *sd = (struct map_session_data *)src;
nullpo_retr(0, sd);
+
+ if (sd->timerskill_count <= 0)
+ return 0;
+
for(i=0;i<MAX_SKILLTIMERSKILL;i++) {
if(sd->skilltimerskill[i].timer != -1) {
delete_timer(sd->skilltimerskill[i].timer, skill_timerskill);
sd->skilltimerskill[i].timer = -1;
+ sd->timerskill_count--;
}
}
}
@@ -2237,27 +2093,37 @@ int skill_cleartimerskill(struct block_list *src)
* iƒXƒpƒQƒbƒeƒB‚ÉŒü‚¯‚Ä‚P?‘OiI(ƒ_ƒƒ|)j
*------------------------------------------
*/
-int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag )
+int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag)
{
- struct map_session_data *sd=NULL;
- struct status_change *sc_data = battle_get_sc_data(src);
+ struct map_session_data *sd = NULL, *tsd = NULL;
+ struct status_change *sc_data;
int i;
- if(skilllv <= 0) return 0;
+ if(skillid < 0)
+ { // remove the debug print when this case is finished
+ printf("skill_castend_damage_id: skillid=%i\ncall: %p %p %i %i %i %i",skillid,
+ src, bl,skillid,skilllv,tick,flag);
+ return 0;
+ }
+ if(skillid > 0 && skilllv <= 0) return 0;
nullpo_retr(1, src);
nullpo_retr(1, bl);
- if(src->type==BL_PC)
- sd=(struct map_session_data *)src;
- if(sd && pc_isdead(sd))
+ sc_data = status_get_sc_data(src);
+
+ if (src->type == BL_PC)
+ sd = (struct map_session_data *)src;
+ if (sd && pc_isdead(sd))
return 1;
- if((skillid == WZ_SIGHTRASHER || skillid == CR_GRANDCROSS) && src != bl)
+ if ((skillid == CR_GRANDCROSS || skillid == NPC_DARKGRANDCROSS) && src != bl)
bl = src;
- if(bl->prev == NULL)
+ if (bl->prev == NULL)
return 1;
- if(bl->type == BL_PC && pc_isdead((struct map_session_data *)bl))
+ if (bl->type == BL_PC)
+ tsd = (struct map_session_data *)bl;
+ if (tsd && pc_isdead(tsd))
return 1;
map_freeblock_lock();
@@ -2270,10 +2136,10 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s
case AS_SONICBLOW: /* ƒ\ƒjƒbƒNƒuƒ? */
case KN_PIERCE: /* ƒsƒA?ƒX */
case KN_SPEARBOOMERANG: /* ƒXƒsƒAƒu?ƒƒ‰ƒ“ */
+ case KN_BRANDISHSPEAR: /* ƒuƒ‰ƒ“ƒfƒBƒbƒVƒ…ƒXƒsƒA */
case TF_POISON: /* ƒCƒ“ƒxƒiƒ€ */
case TF_SPRINKLESAND: /* »‚Ü‚« */
case AC_CHARGEARROW: /* ƒ`ƒƒ?ƒWƒAƒ? */
- case KN_SPEARSTAB: /* ƒXƒsƒAƒXƒ^ƒu */
case RG_RAID: /* ƒTƒvƒ‰ƒCƒYƒAƒ^ƒbƒN */
case RG_INTIMIDATE: /* ƒCƒ“ƒeƒBƒ~ƒfƒCƒg */
case BA_MUSICALSTRIKE: /* ƒ~ƒ…?ƒWƒJƒ‹ƒXƒgƒ‰ƒCƒN */
@@ -2282,7 +2148,6 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s
case CR_HOLYCROSS: /* ƒz?ƒŠ?ƒNƒƒX */
case CR_SHIELDCHARGE:
case CR_SHIELDBOOMERANG:
-
/* ˆÈ‰ºMOB?—p */
/* ??U?ASPŒ¸­U?A‰“‹——£U?A–hŒä–³Ž‹U?A‘½’iU? */
case NPC_PIERCINGATT:
@@ -2311,187 +2176,195 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s
case NPC_HOLYATTACK:
case NPC_DARKNESSATTACK:
case NPC_TELEKINESISATTACK:
+ case NPC_UNDEADATTACK:
+ case NPC_BREAKARMOR:
+ case NPC_BREAKWEAPON:
+ case NPC_BREAKHELM:
+ case NPC_BREAKSHIELD:
case LK_AURABLADE: /* ƒI?ƒ‰ƒuƒŒ?ƒh */
case LK_SPIRALPIERCE: /* ƒXƒpƒCƒ‰ƒ‹ƒsƒA?ƒX */
case LK_HEADCRUSH: /* ƒwƒbƒhƒNƒ‰ƒbƒVƒ… */
case LK_JOINTBEAT: /* ƒWƒ‡ƒCƒ“ƒgƒr?ƒg */
- case PA_PRESSURE: /* ƒvƒŒƒbƒVƒƒ? */
- case PA_SACRIFICE: /* ƒTƒNƒŠƒtƒ@ƒCƒX */
- case SN_SHARPSHOOTING: /* ƒVƒƒ?ƒvƒVƒ…?ƒeƒBƒ“ƒO */
case CG_ARROWVULCAN: /* ƒAƒ?ƒoƒ‹ƒJƒ“ */
- case ASC_BREAKER: /* ƒ\ƒEƒ‹ƒuƒŒ?ƒJ? */
case HW_MAGICCRASHER: /* ƒ}ƒWƒbƒNƒNƒ‰ƒbƒVƒƒ? */
+ case ASC_METEORASSAULT: /* ƒƒeƒIƒAƒTƒ‹ƒg */
+ case ITM_TOMAHAWK:
+ case MO_COMBOFINISH: /* –Ò—´Œ */
+ case CH_CHAINCRUSH: /* ˜A’Œ•ö? */
+ case CH_PALMSTRIKE: /* –ÒŒÕd”hŽR */
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
break;
+
+ case ASC_BREAKER: /* ƒ\ƒEƒ‹ƒuƒŒ?ƒJ? */ // [DracoRPG]
+ // separate weapon and magic attacks
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
+ break;
+
+ case SN_SHARPSHOOTING: /* ƒVƒƒ?ƒvƒVƒ…?ƒeƒBƒ“ƒO */
+ map_foreachinpath (skill_attack_area,src->m, // function, map
+ src->x,src->y, // source xy
+ bl->x,bl->y, // target xy
+ 2,0, // range, type
+ BF_WEAPON,src,src,skillid,skilllv,tick,flag,BCT_ENEMY); // varargs
+ break;
+
+ case PA_PRESSURE: /* ƒvƒŒƒbƒVƒƒ? */
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ if (rand()%100 < 50)
+ status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(PA_PRESSURE,skilllv),0);
+ else
+ status_change_start(bl,SC_BLEEDING,skilllv,0,0,0,skill_get_time2(PA_PRESSURE,skilllv),0);
+ if (tsd) {
+ int sp = tsd->status.max_sp * 10 * skilllv / 100;
+ if (sp > tsd->status.sp) sp = tsd->status.sp;
+ tsd->status.sp -= sp;
+ clif_updatestatus(tsd,SP_SP);
+ }
+ break;
+
case NPC_DARKBREATH:
clif_emotion(src,7);
skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);
break;
+
case MO_INVESTIGATE: /* ?™¤ */
{
- struct status_change *sc_data = battle_get_sc_data(src);
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- if(sc_data[SC_BLADESTOP].timer != -1)
- skill_status_change_end(src,SC_BLADESTOP,-1);
+ if (sc_data && sc_data[SC_BLADESTOP].timer != -1)
+ status_change_end(src,SC_BLADESTOP,-1);
}
break;
+
case SN_FALCONASSAULT: /* ƒtƒ@ƒ‹ƒRƒ“ƒAƒTƒ‹ƒg */
skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);
break;
- case KN_BRANDISHSPEAR: /* ƒuƒ‰ƒ“ƒfƒBƒbƒVƒ…ƒXƒsƒA */
- {
- struct mob_data *md = (struct mob_data *)bl;
- nullpo_retr(1, md);
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- if(md->hp > 0){
- skill_blown(src,bl,skill_get_blewcount(skillid,skilllv));
- if(bl->type == BL_MOB)
- clif_fixmobpos((struct mob_data *)bl);
- else if(bl->type == BL_PET)
- clif_fixpetpos((struct pet_data *)bl);
- else
- clif_fixpos(bl);
- }
- }
- break;
+
case RG_BACKSTAP: /* ƒoƒbƒNƒXƒ^ƒu */
{
- int dir = map_calc_dir(src,bl->x,bl->y),t_dir = battle_get_dir(bl);
- int dist = distance(src->x,src->y,bl->x,bl->y);
- if((dist > 0 && !map_check_dir(dir,t_dir)) || bl->type == BL_SKILL) {
- struct status_change *sc_data = battle_get_sc_data(src);
- if(sc_data && sc_data[SC_HIDING].timer != -1)
- skill_status_change_end(src, SC_HIDING, -1); // ƒnƒCƒfƒBƒ“ƒO‰ðœ
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ int dir = map_calc_dir(src,bl->x,bl->y), t_dir = status_get_dir(bl);
+ int dist = distance(src->x, src->y, bl->x, bl->y);
+ if ((dist > 0 && !map_check_dir(dir, t_dir)) || bl->type == BL_SKILL) {
+ if (sc_data && sc_data[SC_HIDING].timer != -1)
+ status_change_end(src, SC_HIDING, -1); // ƒnƒCƒfƒBƒ“ƒO‰ðœ
+ skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag);
dir = dir < 4 ? dir+4 : dir-4; // change direction [Celest]
- if (bl->type == BL_PC)
- ((struct map_session_data *)bl)->dir=dir;
- else if (bl->type == BL_MOB)
- ((struct mob_data *)bl)->dir=dir;
- //skill_blown(src,bl,skill_get_blewcount(skillid,skilllv));
+ if (tsd)
+ tsd->dir = dir;
+ else if (bl->type == BL_MOB) {
+ struct mob_data *md = (struct mob_data *)bl;
+ if (md) md->dir = dir;
+ }
+ clif_changed_dir(bl);
}
- else if(src->type == BL_PC)
+ else if (sd)
clif_skill_fail(sd,sd->skillid,0,0);
}
break;
case AM_ACIDTERROR: /* ƒAƒVƒbƒhƒeƒ‰? */
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- if(bl->type == BL_PC && rand()%100 < skill_get_time(skillid,skilllv) && battle_config.equipment_breaking)
- pc_breakarmor((struct map_session_data *)bl);
+ skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag);
+ if (tsd && battle_config.equipment_breaking && rand()%100 < skill_get_time(skillid,skilllv)) {
+ pc_breakarmor(tsd);
+ clif_emotion(bl, 23);
+ }
break;
+
case MO_FINGEROFFENSIVE: /* Žw? */
{
- struct status_change *sc_data = battle_get_sc_data(src);
-
- if(!battle_config.finger_offensive_type)
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- else {
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- if(sd) {
- for(i=1;i<sd->spiritball_old;i++)
- skill_addtimerskill(src,tick+i*200,bl->id,0,0,skillid,skilllv,BF_WEAPON,flag);
- sd->canmove_tick = tick + (sd->spiritball_old-1)*200;
- }
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ if (battle_config.finger_offensive_type && sd) {
+ for (i = 1; i < sd->spiritball_old; i++)
+ skill_addtimerskill(src, tick + i * 200, bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag);
+ sd->canmove_tick = tick + (sd->spiritball_old - 1) * 200;
}
- if(sc_data && sc_data[SC_BLADESTOP].timer != -1)
- skill_status_change_end(src,SC_BLADESTOP,-1);
+ if (sc_data && sc_data[SC_BLADESTOP].timer != -1)
+ status_change_end(src,SC_BLADESTOP,-1);
}
break;
+
case MO_CHAINCOMBO: /* ˜A‘Ŷ */
{
- struct status_change *sc_data = battle_get_sc_data(src);
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- if(sc_data && sc_data[SC_BLADESTOP].timer != -1)
- skill_status_change_end(src,SC_BLADESTOP,-1);
+ if (sc_data && sc_data[SC_BLADESTOP].timer != -1)
+ status_change_end(src,SC_BLADESTOP,-1);
}
break;
- case MO_COMBOFINISH: /* –Ò—´Œ */
+
case CH_TIGERFIST: /* •šŒÕŒ */
- case CH_CHAINCRUSH: /* ˜A’Œ•ö? */
- case CH_PALMSTRIKE: /* –ÒŒÕd”hŽR */
+ if (tsd && !(map[bl->m].flag.gvg || map[bl->m].flag.pvp)) {
+ map_freeblock_unlock();
+ return 1;
+ }
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
break;
+
case MO_EXTREMITYFIST: /* ˆ¢C—…”e–PŒ */
{
- struct status_change *sc_data = battle_get_sc_data(src);
+ if(sd) {
+ struct walkpath_data wpd;
+ int dx,dy;
- if(sd) {
- struct walkpath_data wpd;
- int dx,dy;
-
- dx = bl->x - sd->bl.x;
- dy = bl->y - sd->bl.y;
- if(dx > 0) dx++;
- else if(dx < 0) dx--;
- if(dy > 0) dy++;
- else if(dy < 0) dy--;
- if(dx == 0 && dy == 0) dx++;
- if(path_search(&wpd,src->m,sd->bl.x,sd->bl.y,sd->bl.x+dx,sd->bl.y+dy,1) == -1) {
dx = bl->x - sd->bl.x;
dy = bl->y - sd->bl.y;
- if(path_search(&wpd,src->m,sd->bl.x,sd->bl.y,sd->bl.x+dx,sd->bl.y+dy,1) == -1) {
- clif_skill_fail(sd,sd->skillid,0,0);
- break;
+ if(dx > 0) dx++;
+ else if(dx < 0) dx--;
+ if (dy > 0) dy++;
+ else if(dy < 0) dy--;
+ if(dx == 0 && dy == 0) dx++;
+ if (path_search(&wpd,src->m,sd->bl.x,sd->bl.y,sd->bl.x+dx,sd->bl.y+dy,1) == -1) {
+ dx = bl->x - sd->bl.x;
+ dy = bl->y - sd->bl.y;
+ if(path_search(&wpd,src->m,sd->bl.x,sd->bl.y,sd->bl.x+dx,sd->bl.y+dy,1) == -1) {
+ clif_skill_fail(sd,sd->skillid,0,0);
+ break;
+ }
}
+ sd->to_x = sd->bl.x + dx;
+ sd->to_y = sd->bl.y + dy;
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ clif_walkok(sd);
+ clif_movechar(sd);
+ if(dx < 0) dx = -dx;
+ if(dy < 0) dy = -dy;
+ sd->attackabletime = sd->canmove_tick = tick + 100 + sd->speed * ((dx > dy)? dx:dy);
+ if(sd->canact_tick < sd->canmove_tick)
+ sd->canact_tick = sd->canmove_tick;
+ pc_movepos(sd,sd->to_x,sd->to_y);
+ status_change_end(&sd->bl,SC_COMBO,-1);
}
- sd->to_x = sd->bl.x + dx;
- sd->to_y = sd->bl.y + dy;
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- clif_walkok(sd);
- clif_movechar(sd);
- if(dx < 0) dx = -dx;
- if(dy < 0) dy = -dy;
- sd->attackabletime = sd->canmove_tick = tick + 100 + sd->speed * ((dx > dy)? dx:dy);
- if(sd->canact_tick < sd->canmove_tick)
- sd->canact_tick = sd->canmove_tick;
- pc_movepos(sd,sd->to_x,sd->to_y);
- skill_status_change_end(&sd->bl,SC_COMBO,-1);
- }
- else
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- skill_status_change_end(src, SC_EXPLOSIONSPIRITS, -1);
- if(sc_data && sc_data[SC_BLADESTOP].timer != -1)
- skill_status_change_end(src,SC_BLADESTOP,-1);
+ else
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ status_change_end(src, SC_EXPLOSIONSPIRITS, -1);
+ if (sc_data && sc_data[SC_BLADESTOP].timer != -1)
+ status_change_end(src,SC_BLADESTOP,-1);
}
break;
+
/* •ŠíŒn”Í?U?ƒXƒLƒ‹ */
case AC_SHOWER: /* ƒAƒ?ƒVƒƒƒ? */
- case SM_MAGNUM: /* ƒ}ƒOƒiƒ€ƒuƒŒƒCƒN */
case AS_GRIMTOOTH: /* ƒOƒŠƒ€ƒgƒD?ƒX */
case MC_CARTREVOLUTION: /* ƒJ?ƒgƒŒƒ”ƒHƒŠƒ…?ƒVƒ‡ƒ“ */
case NPC_SPLASHATTACK: /* ƒXƒvƒ‰ƒbƒVƒ…ƒAƒ^ƒbƒN */
- case ASC_METEORASSAULT: /* ƒƒeƒIƒAƒTƒ‹ƒg */
case AS_SPLASHER: /* [Valaris] */
if(flag&1){
/* ŒÂ•ʂɃ_ƒ?ƒW‚ð?‚¦‚é */
if(bl->id!=skill_area_temp[1]){
- int dist=0;
- if(skillid==SM_MAGNUM){ /* ƒ}ƒOƒiƒ€ƒuƒŒƒCƒN‚Ȃ璆S‚©‚ç‚Ì‹——£‚ðŒvŽZ */
- int dx=abs( bl->x - skill_area_temp[2] );
- int dy=abs( bl->y - skill_area_temp[3] );
- dist=((dx>dy)?dx:dy);
- }
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,
- 0x0500|dist );
+ 0x0500);
}
- }else{
- int ar=1;
- int x=bl->x,y=bl->y;
- if( skillid==SM_MAGNUM){
- x=src->x;
- y=src->y;
- }else if(skillid==AC_SHOWER || skillid==ASC_METEORASSAULT) /* ƒAƒ?ƒVƒƒƒ?AƒƒeƒIƒAƒTƒ‹ƒg”Í?5*5 */
- ar=2;
- else if(skillid==AS_SPLASHER) /* ƒxƒiƒ€ƒXƒvƒ‰ƒbƒVƒƒ?”Í?3*3 */
- ar=1;
- else if(skillid==NPC_SPLASHATTACK) /* ƒXƒvƒ‰ƒbƒVƒ…ƒAƒ^ƒbƒN‚Í”Í?7*7 */
- ar=3;
-
- // meteor assault cast effect (not sure how else to properly add it =p) [Celest]
- if (skillid == ASC_METEORASSAULT)
- clif_specialeffect(&sd->bl,409, 1);
-
+ } else {
+ int ar = 1;
+ int x = bl->x, y = bl->y;
+ switch (skillid) {
+ case AC_SHOWER:
+ ar=2;
+ break;
+ case NPC_SPLASHATTACK:
+ ar=3;
+ break;
+ }
+
skill_area_temp[1]=bl->id;
skill_area_temp[2]=x;
skill_area_temp[3]=y;
@@ -2502,13 +2375,24 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s
bl->m,x-ar,y-ar,x+ar,y+ar,0,
src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
skill_castend_damage_id);
- if (skillid == SM_MAGNUM) // fire element for 10 seconds
- skill_status_change_start(src,SC_FLAMELAUNCHER,0,0,0,0,10000,0);
}
- if (bl->type == BL_MOB && skillid == AS_GRIMTOOTH) {
- struct status_change *sc_data = battle_get_sc_data(bl);
- if (sc_data && sc_data[SC_SLOWDOWN].timer == -1)
- skill_status_change_start(bl,SC_SLOWDOWN,0,0,0,0,1000,0);
+ break;
+
+ case SM_MAGNUM: /* ƒ}ƒOƒiƒ€ƒuƒŒƒCƒN [celest] */
+ if(flag&1 && bl->id != skill_area_temp[1]){
+ int dist = distance (bl->x, bl->y, skill_area_temp[2], skill_area_temp[3]);
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,
+ 0x0500|dist);
+ } else {
+ skill_area_temp[1]=src->id;
+ skill_area_temp[2]=src->x;
+ skill_area_temp[3]=src->y;
+ map_foreachinarea(skill_area_sub,
+ src->m,src->x-2,src->y-2,src->x+2,src->y+2,0,
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
+ skill_castend_damage_id);
+ status_change_start (src,SC_FLAMELAUNCHER,0,0,0,0,10000,0);
+ clif_skill_nodamage (src,src,skillid,skilllv,1);
}
break;
@@ -2517,13 +2401,11 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s
/* ŒÂ•ʂɃ_ƒ?ƒW‚ð?‚¦‚é */
if(bl->id!=skill_area_temp[1])
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0x0500);
- }
- else {
- int damage;
- map_freeblock_lock();
- damage = skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0);
- if(damage > 0) {
+ } else {
int i,c; /* ‘¼l‚©‚ç•·‚¢‚½“®‚«‚Ȃ̂ŊԈá‚Á‚Ä‚é‰Â”\«‘å•?—¦‚ª?‚¢‚Á‚·„ƒ */
+ /* ‚Ü‚¸ƒ^[ƒQƒbƒg‚ÉUŒ‚‚ð‰Á‚¦‚é */
+ if (!skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0))
+ break;
c = skill_get_blewcount(skillid,skilllv);
if(map[bl->m].flag.gvg) c = 0;
for(i=0;i<c;i++){
@@ -2542,24 +2424,42 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s
if(skill_area_temp[0]>1) break;
}
skill_area_temp[1]=bl->id;
- skill_area_temp[2]=bl->x;
- skill_area_temp[3]=bl->y;
/* ‚»‚ÌŒãƒ^?ƒQƒbƒgˆÈŠO‚Ì”Í??‚Ì“G‘S?‚É?—‚ðs‚¤ */
map_foreachinarea(skill_area_sub,
bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,0,
src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
skill_castend_damage_id);
- battle_damage(src,bl,damage,1);
- if(rdamage > 0)
- battle_damage(bl,src,rdamage,0);
+ }
+ break;
+
+ case KN_SPEARSTAB: /* ƒXƒsƒAƒXƒ^ƒu */
+ if(flag&1){
+ /* ŒÂ•ʂɃ_ƒ[ƒW‚ð—^‚¦‚é */
+ if (bl->id==skill_area_temp[1])
+ break;
+ if (skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0x0500))
+ skill_blown(src,bl,skill_area_temp[2]);
+ } else {
+ int x=bl->x,y=bl->y,i,dir;
+ /* ‚Ü‚¸ƒ^[ƒQƒbƒg‚ÉUŒ‚‚ð‰Á‚¦‚é */
+ dir = map_calc_dir(bl,src->x,src->y);
+ skill_area_temp[1] = bl->id;
+ skill_area_temp[2] = skill_get_blewcount(skillid,skilllv)|dir<<20;
+ if (skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0))
+ skill_blown(src,bl,skill_area_temp[2]);
+ for (i=0;i<4;i++) {
+ map_foreachinarea(skill_area_sub,bl->m,x,y,x,y,0,
+ src,skillid,skilllv,tick,flag|BCT_ENEMY|1,
+ skill_castend_damage_id);
+ x += dirx[dir];
+ y += diry[dir];
}
- map_freeblock_unlock();
}
break;
case ALL_RESURRECTION: /* ƒŠƒUƒŒƒNƒVƒ‡ƒ“ */
case PR_TURNUNDEAD: /* ƒ^?ƒ“ƒAƒ“ƒfƒbƒh */
- if(bl->type != BL_PC && battle_check_undead(battle_get_race(bl),battle_get_elem_type(bl)))
+ if(bl->type != BL_PC && battle_check_undead(status_get_race(bl),status_get_elem_type(bl)))
skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
else {
map_freeblock_unlock();
@@ -2569,67 +2469,95 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s
/* –‚–@ŒnƒXƒLƒ‹ */
case MG_SOULSTRIKE: /* ƒ\ƒEƒ‹ƒXƒgƒ‰ƒCƒN */
- case MG_COLDBOLT: /* ƒR?ƒ‹ƒhƒ{ƒ‹ƒg */
- case MG_FIREBOLT: /* ƒtƒ@ƒCƒA?ƒ{ƒ‹ƒg */
+ case NPC_DARKSOULSTRIKE: /*ˆÅƒ\ƒEƒ‹ƒXƒgƒ‰ƒCƒN*/
+ case MG_COLDBOLT: /* ƒR[ƒ‹ƒhƒ{ƒ‹ƒg */
+ case MG_FIREBOLT: /* ƒtƒ@ƒCƒA[ƒ{ƒ‹ƒg */
case MG_LIGHTNINGBOLT: /* ƒ‰ƒCƒgƒjƒ“ƒOƒ{ƒ‹ƒg */
- case WZ_EARTHSPIKE: /* ƒA?ƒXƒXƒpƒCƒN */
- case AL_HEAL: /* ƒq?ƒ‹ */
- case AL_HOLYLIGHT: /* ƒz?ƒŠ?ƒ‰ƒCƒg */
- case MG_FROSTDIVER: /* ƒtƒƒXƒgƒ_ƒCƒo? */
- case WZ_JUPITEL: /* ƒ†ƒsƒeƒ‹ƒTƒ“ƒ_? */
+ case WZ_EARTHSPIKE: /* ƒA[ƒXƒXƒpƒCƒN */
+ case AL_HEAL: /* ƒq[ƒ‹ */
+ case AL_HOLYLIGHT: /* ƒz[ƒŠ[ƒ‰ƒCƒg */
+ case WZ_JUPITEL: /* ƒ†ƒsƒeƒ‹ƒTƒ“ƒ_[ */
+ case NPC_DARKJUPITEL: /*ˆÅƒ†ƒsƒeƒ‹*/
case NPC_MAGICALATTACK: /* MOB:–‚–@‘Å?U? */
case PR_ASPERSIO: /* ƒAƒXƒyƒ‹ƒVƒI */
-// case HW_NAPALMVULCAN: /* ƒiƒp[ƒ€ƒoƒ‹ƒJƒ“ */
+ case MG_FROSTDIVER: /* ƒtƒƒXƒgƒ_ƒCƒo[ */
skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
break;
case WZ_WATERBALL: /* ƒEƒH?ƒ^?ƒ{?ƒ‹ */
skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
- if(skilllv>1)
- skill_status_change_start(src,SC_WATERBALL,skilllv,bl->id,0,0,0,0);
+ if (skilllv>1) {
+ int cnt,range;
+ range = skilllv>5?2:skilllv/2;
+ if (sd)
+ cnt = skill_count_water(src,range)-1;
+ else
+ cnt = skill_get_num(skillid,skilllv)-1;
+ if (cnt>0)
+ skill_addtimerskill(src,tick+150,bl->id,0,0,
+ skillid,skilllv,cnt,flag);
+ }
break;
case PR_BENEDICTIO: /* ¹?~•Ÿ */
- if(battle_get_race(bl)==1 || battle_get_race(bl)==6)
+ if(status_get_race(bl)==1 || status_get_race(bl)==6)
skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
break;
/* –‚–@Œn”Í?U?ƒXƒLƒ‹ */
case MG_NAPALMBEAT: /* ƒiƒp?ƒ€ƒr?ƒg */
case MG_FIREBALL: /* ƒtƒ@ƒCƒ„?ƒ{?ƒ‹ */
- if(flag&1){
+ case WZ_SIGHTRASHER: /* ƒTƒCƒgƒ‰ƒbƒVƒƒ[ */
+ if (flag & 1) {
/* ŒÂ•ʂɃ_ƒ?ƒW‚ð?‚¦‚é */
- if(bl->id!=skill_area_temp[1]){
- if(skillid==MG_FIREBALL){ /* ƒtƒ@ƒCƒ„?ƒ{?ƒ‹‚Ȃ璆S‚©‚ç‚Ì‹——£‚ðŒvŽZ */
- int dx=abs( bl->x - skill_area_temp[2] );
- int dy=abs( bl->y - skill_area_temp[3] );
- skill_area_temp[0]=((dx>dy)?dx:dy);
+ if (bl->id != skill_area_temp[1]){
+ if(skillid == MG_FIREBALL){ /* ƒtƒ@ƒCƒ„?ƒ{?ƒ‹‚Ȃ璆S‚©‚ç‚Ì‹——£‚ðŒvŽZ */
+ skill_area_temp[0] = distance(bl->x, bl->y, skill_area_temp[2], skill_area_temp[3]);
}
skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,
skill_area_temp[0]| 0x0500);
}
- }else{
- int ar=(skillid==MG_NAPALMBEAT)?1:2;
+ } else {
+ int ar;
+ skill_area_temp[0]=0;
skill_area_temp[1]=bl->id;
- if(skillid==MG_NAPALMBEAT){ /* ƒiƒp?ƒ€‚Å‚Íæ‚É?‚¦‚é */
- skill_area_temp[0]=0;
- map_foreachinarea(skill_area_sub,
- bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,0,
- src,skillid,skilllv,tick, flag|BCT_ENEMY ,
- skill_area_sub_count);
- }else{
- skill_area_temp[0]=0;
- skill_area_temp[2]=bl->x;
- skill_area_temp[3]=bl->y;
+ switch (skillid) {
+ case MG_NAPALMBEAT:
+ ar = 1;
+ /* ƒiƒp[ƒ€ƒr[ƒg‚Í•ªŽUƒ_ƒ[ƒW‚Ȃ̂œG‚Ì”‚𔂦‚é */
+ map_foreachinarea(skill_area_sub,
+ bl->m,bl->x-ar,bl->y-ar,bl->x+ar,bl->y+ar,0,
+ src,skillid,skilllv,tick,flag|BCT_ENEMY,
+ skill_area_sub_count);
+ break;
+ case MG_FIREBALL:
+ ar = 2;
+ skill_area_temp[2]=bl->x;
+ skill_area_temp[3]=bl->y;
+ /* ƒ^[ƒQƒbƒg‚ÉUŒ‚‚ð‰Á‚¦‚é(ƒXƒLƒ‹ƒGƒtƒFƒNƒg•\ަ) */
+ skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,
+ skill_area_temp[0]);
+ break;
+ case WZ_SIGHTRASHER:
+ default:
+ ar = 3;
+ bl = src;
+ status_change_end(src,SC_SIGHT,-1);
+ break;
}
- /* ‚Ü‚¸ƒ^?ƒQƒbƒg‚ÉU?‚ð‰Á‚¦‚é */
- skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,
- skill_area_temp[0] );
- /* ‚»‚ÌŒãƒ^?ƒQƒbƒgˆÈŠO‚Ì”Í??‚Ì“G‘S?‚É?—‚ðs‚¤ */
+ if (skillid==WZ_SIGHTRASHER) {
+ /* ƒXƒLƒ‹ƒGƒtƒFƒNƒg•\ަ */
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ } else {
+ /* ƒ^[ƒQƒbƒg‚ÉUŒ‚‚ð‰Á‚¦‚é(ƒXƒLƒ‹ƒGƒtƒFƒNƒg•\ަ) */
+ skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,
+ skill_area_temp[0]);
+ }
+ /* ƒ^[ƒQƒbƒgˆÈŠO‚͈͓̔à‚Ì“G‘S‘̂Ɉ—‚ðs‚¤ */
map_foreachinarea(skill_area_sub,
- bl->m,bl->x-ar,bl->y-ar,bl->x+ar,bl->y+ar,0,
- src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
- skill_castend_damage_id);
+ bl->m,bl->x-ar,bl->y-ar,bl->x+ar,bl->y+ar,0,
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
+ skill_castend_damage_id);
}
break;
@@ -2663,15 +2591,7 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s
break;
case WZ_FROSTNOVA: /* ƒtƒƒXƒgƒmƒ”ƒ@ */
- skill_castend_pos2(src,bl->x,bl->y,skillid,skilllv,tick,0);
- //skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
- map_foreachinarea(skill_attack_area,src->m,src->x-5,bl->y-5,bl->x+5,bl->y+5,0,BF_MAGIC,src,src,skillid,skilllv,tick,flag,BCT_ENEMY);
- break;
-
- case WZ_SIGHTRASHER:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_castend_pos2(src,bl->x,bl->y,skillid,skilllv,tick,0);
- skill_status_change_end(src,SC_SIGHT,-1);
+ map_foreachinarea(skill_attack_area,src->m,src->x-5,bl->y-5,bl->x+5,bl->y+5,0,BF_MAGIC,src,src,skillid,skilllv,tick,flag,BCT_ENEMY);
break;
/* ‚»‚Ì‘¼ */
@@ -2697,6 +2617,7 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s
break;
case CR_GRANDCROSS: /* ƒOƒ‰ƒ“ƒhƒNƒƒX */
+ case NPC_DARKGRANDCROSS: /*ˆÅƒOƒ‰ƒ“ƒhƒNƒƒX*/
/* ƒXƒLƒ‹ƒ†ƒjƒbƒg”z’u */
skill_castend_pos2(src,bl->x,bl->y,skillid,skilllv,tick,0);
if(sd)
@@ -2710,6 +2631,32 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s
skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,0 );
break;
+ // Celest
+ case PF_SOULBURN:
+ {
+ int per = skilllv < 5 ? 20+ skilllv*10 : 60;
+ if (rand()%100 < per) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if (skilllv == 5)
+ skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,0 );
+ if (tsd && (map[src->m].flag.pvp || map[src->m].flag.gvg)) {
+ tsd->status.sp = 0;
+ clif_updatestatus(tsd,SP_SP);
+ }
+ } else {
+ clif_skill_nodamage(src,src,skillid,skilllv,1);
+ if (skilllv == 5)
+ skill_attack(BF_MAGIC,src,src,src,skillid,skilllv,tick,0 );
+ if (sd) {
+ sd->status.sp = 0;
+ clif_updatestatus(sd,SP_SP);
+ }
+ }
+ if (sd)
+ pc_blockskill_start (sd, skillid, (skilllv < 5 ? 10000: 15000));
+ }
+ break;
+
case NPC_SELFDESTRUCTION: /* Ž©”š */
case NPC_SELFDESTRUCTION2: /* Ž©”š2 */
if(flag&1){
@@ -2726,7 +2673,7 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s
struct mob_data *md;
if((md=(struct mob_data *)src)){
skill_area_temp[1]=bl->id;
- skill_area_temp[2]=battle_get_hp(src);
+ skill_area_temp[2]=status_get_hp(src);
clif_skill_nodamage(src,src,NPC_SELFDESTRUCTION,-1,1);
map_foreachinarea(skill_area_sub,
bl->m,bl->x-5,bl->y-5,bl->x+5,bl->y+5,0,
@@ -2754,6 +2701,14 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s
}
}
break;
+
+ // unknown skills [Celest]
+ case NPC_BIND:
+ case NPC_EXPLOSIONSPIRITS:
+ case NPC_INCAGI:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ break;
+
case 0:
if(sd) {
if(flag&3){
@@ -2772,12 +2727,13 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s
break;
default:
+ printf("Unknown skill used:%d\n",skillid);
map_freeblock_unlock();
return 1;
}
if(sc_data) {
if (sc_data[SC_MAGICPOWER].timer != -1 && skillid != HW_MAGICPOWER) //ƒ}ƒWƒbƒNƒpƒ?‚Ì?‰ÊI—¹
- skill_status_change_end(src,SC_MAGICPOWER,-1);
+ status_change_end(src,SC_MAGICPOWER,-1);
}
map_freeblock_unlock();
@@ -2788,107 +2744,96 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s
* ƒXƒLƒ‹Žg—pi‰r¥Š®—¹AIDŽw’èŽx‰‡Œnj
*------------------------------------------
*/
-int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag )
+int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, int skillid, int skilllv, unsigned int tick, int flag)
{
- struct map_session_data *sd=NULL;
- struct map_session_data *dstsd=NULL;
- struct mob_data *md=NULL;
- struct mob_data *dstmd=NULL;
- int i,abra_skillid=0,abra_skilllv;
- int sc_def_vit,sc_def_mdef,strip_fix,strip_time,strip_per;
- int sc_dex,sc_luk;
- //ƒNƒ‰ƒXƒ`ƒFƒ“ƒW—pƒ{ƒXƒ‚ƒ“ƒXƒ^?ID
- int changeclass[]={1038,1039,1046,1059,1086,1087,1112,1115
- ,1157,1159,1190,1272,1312,1373,1492};
- int poringclass[]={1002};
-
- if(skilllv <= 0) return 0;
+ struct map_session_data *sd = NULL;
+ struct map_session_data *dstsd = NULL;
+ struct mob_data *md = NULL;
+ struct mob_data *dstmd = NULL;
+ int i;
+ int sc_def_vit, sc_def_mdef;
+ int sc_dex, sc_luk;
+
+ if(skillid < 0)
+ { // remove the debug print when this case is finished
+ printf("skill_castend_damage_id: skillid=%i\ncall: %p %p %i %i %i %i",skillid,
+ src, bl,skillid,skilllv,tick,flag);
+ return 0;
+ }
+ if(skillid > 0 && skilllv <= 0) return 0; // celest
nullpo_retr(1, src);
nullpo_retr(1, bl);
- if(src->type==BL_PC)
- sd=(struct map_session_data *)src;
- else if(src->type==BL_MOB)
- md=(struct mob_data *)src;
-
- sc_dex=battle_get_mdef(bl);
- sc_luk=battle_get_luk(bl);
- sc_def_vit = 100 - (3 + battle_get_vit(bl) + battle_get_luk(bl)/3);
- //sc_def_vit = 100 - (3 + battle_get_vit(bl) + battle_get_luk(bl)/3);
- sc_def_mdef = 100 - (3 + battle_get_mdef(bl) + battle_get_luk(bl)/3);
- strip_fix = battle_get_dex(src) - battle_get_dex(bl);
-
- if(bl->type==BL_PC){
- nullpo_retr(1, dstsd=(struct map_session_data *)bl);
- }else if(bl->type==BL_MOB){
- nullpo_retr(1, dstmd=(struct mob_data *)bl);
- if(sc_def_vit>50)
- sc_def_vit=50;
- if(sc_def_mdef>50)
- sc_def_mdef=50;
- }
- if(sc_def_vit < 0)
- sc_def_vit=0;
- if(sc_def_mdef < 0)
- sc_def_mdef=0;
- if(strip_fix < 0)
- strip_fix=0;
-
- if(bl == NULL || bl->prev == NULL)
+ if (src->type == BL_PC) {
+ nullpo_retr (1, sd = (struct map_session_data *)src);
+ } else if (src->type == BL_MOB) {
+ nullpo_retr (1, md = (struct mob_data *)src);
+ }
+
+ sc_dex = status_get_mdef (bl);
+ sc_luk = status_get_luk (bl);
+ sc_def_vit = status_get_sc_def_vit (bl);
+ sc_def_mdef = status_get_sc_def_mdef (bl);
+
+ if (bl->type == BL_PC){
+ nullpo_retr (1, dstsd = (struct map_session_data *)bl);
+ } else if (bl->type == BL_MOB){
+ nullpo_retr (1, dstmd = (struct mob_data *)bl);
+ }
+
+ if(bl->prev == NULL)
return 1;
if(sd && pc_isdead(sd))
return 1;
if(dstsd && pc_isdead(dstsd) && skillid != ALL_RESURRECTION)
return 1;
- if(battle_get_class(bl) == 1288)
+ if(status_get_class(bl) == 1288)
return 1;
- if (skillnotok(skillid, (struct map_session_data *)bl)) // [MouseJstr]
+ if (sd && skillnotok(skillid, sd)) // [MouseJstr]
return 0;
-
+
map_freeblock_lock();
switch(skillid)
{
case AL_HEAL: /* ƒq?ƒ‹ */
{
- int heal=skill_calc_heal( src, skilllv );
+ int heal = skill_calc_heal(src, skilllv);
int heal_get_jobexp;
int skill;
- struct pc_base_job s_class;
- if( dstsd && dstsd->special_state.no_magic_damage )
+ if (skilllv > 10)
+ heal = 9999; //9999ƒq[ƒ‹
+ if (dstsd && dstsd->special_state.no_magic_damage)
heal=0; /* ?‹à峃J?ƒhiƒq?ƒ‹—Ê‚Oj */
- if (sd){
- s_class = pc_calc_base_job(sd->status.class);
- if((skill=pc_checkskill(sd,HP_MEDITATIO))>0) // ƒƒfƒBƒeƒCƒeƒBƒI
- heal += heal*skill*2/100;
- if(sd && dstsd && sd->status.partner_id == dstsd->status.char_id && s_class.job == 23 && sd->status.sex == 0) //Ž©•ª‚à?Û‚àPCA?Û‚ªŽ©•ª‚̃p?ƒgƒi?AŽ©•ª‚ªƒXƒpƒmƒrAŽ©•ª‚ªŠ‚È‚ç
+ if (sd) {
+ if ((skill = pc_checkskill(sd, HP_MEDITATIO)) > 0) // ƒƒfƒBƒeƒCƒeƒBƒI
+ heal += heal * skill * 2 / 100;
+ if (sd && dstsd && sd->status.partner_id == dstsd->status.char_id &&
+ pc_calc_base_job2(sd->status.class_) == 23 && sd->status.sex == 0) //Ž©•ª‚à?Û‚àPCA?Û‚ªŽ©•ª‚̃p?ƒgƒi?AŽ©•ª‚ªƒXƒpƒmƒrAŽ©•ª‚ªŠ‚È‚ç
heal = heal*2; //ƒXƒpƒmƒr‚̉łª’U“߂Ƀq?ƒ‹‚·‚邯2”{‚ɂȂé
}
-
- clif_skill_nodamage(src,bl,skillid,heal,1);
+ clif_skill_nodamage (src, bl, skillid, heal, 1);
heal_get_jobexp = battle_heal(NULL,bl,heal,0,0);
// JOB??’lŠl“¾
- if(src->type == BL_PC && bl->type==BL_PC && heal > 0 && src != bl && battle_config.heal_exp > 0){
+ if(sd && dstsd && heal > 0 && sd != dstsd && battle_config.heal_exp > 0){
heal_get_jobexp = heal_get_jobexp * battle_config.heal_exp / 100;
- if(heal_get_jobexp <= 0)
+ if (heal_get_jobexp <= 0)
heal_get_jobexp = 1;
- pc_gainexp((struct map_session_data *)src,0,heal_get_jobexp);
+ pc_gainexp (sd, 0, heal_get_jobexp);
}
}
break;
case ALL_RESURRECTION: /* ƒŠƒUƒŒƒNƒVƒ‡ƒ“ */
- if(bl->type==BL_PC){
- int per=0;
- struct map_session_data *tsd = (struct map_session_data*)bl;
- nullpo_retr(1, tsd);
- if( (map[bl->m].flag.pvp) && tsd->pvp_point<0 )
+ if(dstsd) {
+ int per = 0;
+ if (map[bl->m].flag.pvp && dstsd->pvp_point < 0)
break; /* PVP‚Å•œŠˆ•s‰Â”\?‘Ô */
- if(pc_isdead(tsd)){ /* Ž€–S”»’è */
+ if (pc_isdead(dstsd)) { /* Ž€–S”»’è */
clif_skill_nodamage(src,bl,skillid,skilllv,1);
switch(skilllv){
case 1: per=10; break;
@@ -2896,139 +2841,153 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
case 3: per=50; break;
case 4: per=80; break;
}
- tsd->status.hp=tsd->status.max_hp*per/100;
- if(tsd->status.hp<=0) tsd->status.hp=1;
- if(tsd->special_state.restart_full_recover ){ /* ƒIƒVƒŠƒXƒJ?ƒh */
- tsd->status.hp=tsd->status.max_hp;
- tsd->status.sp=tsd->status.max_sp;
+ dstsd->status.hp = dstsd->status.max_hp * per / 100;
+ if (dstsd->status.hp <= 0) dstsd->status.hp = 1;
+ if (dstsd->special_state.restart_full_recover) { /* ƒIƒVƒŠƒXƒJ?ƒh */
+ dstsd->status.hp = dstsd->status.max_hp;
+ dstsd->status.sp = dstsd->status.max_sp;
}
- pc_setstand(tsd);
+ pc_setstand(dstsd);
if(battle_config.pc_invincible_time > 0)
- pc_setinvincibletimer(tsd,battle_config.pc_invincible_time);
- clif_updatestatus(tsd,SP_HP);
- clif_resurrection(&tsd->bl,1);
- if(src != bl && sd && battle_config.resurrection_exp > 0) {
+ pc_setinvincibletimer(dstsd, battle_config.pc_invincible_time);
+ clif_updatestatus(dstsd, SP_HP);
+ clif_resurrection(bl, 1);
+ if(sd && sd != dstsd && battle_config.resurrection_exp > 0) {
int exp = 0,jexp = 0;
- int lv = tsd->status.base_level - sd->status.base_level, jlv = tsd->status.job_level - sd->status.job_level;
+ int lv = dstsd->status.base_level - sd->status.base_level, jlv = dstsd->status.job_level - sd->status.job_level;
if(lv > 0) {
- exp = (int)((double)tsd->status.base_exp * (double)lv * (double)battle_config.resurrection_exp / 1000000.);
- if(exp < 1) exp = 1;
+ exp = (int)((double)dstsd->status.base_exp * (double)lv * (double)battle_config.resurrection_exp / 1000000.);
+ if (exp < 1) exp = 1;
}
if(jlv > 0) {
- jexp = (int)((double)tsd->status.job_exp * (double)lv * (double)battle_config.resurrection_exp / 1000000.);
- if(jexp < 1) jexp = 1;
+ jexp = (int)((double)dstsd->status.job_exp * (double)lv * (double)battle_config.resurrection_exp / 1000000.);
+ if (jexp < 1) jexp = 1;
}
if(exp > 0 || jexp > 0)
- pc_gainexp(sd,exp,jexp);
+ pc_gainexp (sd, exp, jexp);
}
}
}
break;
case AL_DECAGI: /* ‘¬“xŒ¸­ */
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage )
+ if (dstsd && dstsd->special_state.no_magic_damage)
break;
- if( rand()%100 < (50+skilllv*3+(battle_get_lv(src)+battle_get_int(src)/5)-sc_def_mdef) ) {
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
+ if (rand() % 100 < (50 + skilllv * 3 + (status_get_lv(src) + status_get_int(src) / 5) - sc_def_mdef)) {
+ clif_skill_nodamage (src, bl, skillid, skilllv, 1);
+ status_change_start (bl, SkillStatusChangeTable[skillid], skilllv, 0, 0, 0, skill_get_time(skillid,skilllv), 0);
}
break;
case AL_CRUCIS:
- if(flag&1) {
- int race = battle_get_race(bl),ele = battle_get_elem_type(bl);
- if(battle_check_target(src,bl,BCT_ENEMY) && (race == 6 || battle_check_undead(race,ele))) {
- int slv=battle_get_lv(src),tlv=battle_get_lv(bl),rate;
- rate = 25 + skilllv*2 + slv - tlv;
- if(rand()%100 < rate)
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,0,0);
+ if (flag & 1) {
+ int race = status_get_race (bl), ele = status_get_elem_type (bl);
+ if (battle_check_target (src, bl, BCT_ENEMY) && (race == 6 || battle_check_undead (race, ele))) {
+ int slv = status_get_lv (src),tlv = status_get_lv (bl);
+ int rate = 25 + skilllv*2 + slv - tlv;
+ if (rand()%100 < rate)
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,0,0);
}
- }
- else {
- int range = 15;
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ } else {
+ clif_skill_nodamage(src, bl, skillid, skilllv, 1);
map_foreachinarea(skill_area_sub,
- src->m,src->x-range,src->y-range,src->x+range,src->y+range,0,
- src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
+ src->m, src->x-15, src->y-15, src->x+15, src->y+15, 0,
+ src, skillid, skilllv, tick, flag|BCT_ENEMY|1,
skill_castend_nodamage_id);
}
break;
case PR_LEXDIVINA: /* ƒŒƒbƒNƒXƒfƒBƒr?ƒi */
{
- struct status_change *sc_data = battle_get_sc_data(bl);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage )
+ struct status_change *sc_data = status_get_sc_data(bl);
+ clif_skill_nodamage (src, bl, skillid, skilllv, 1);
+ if (dstsd && dstsd->special_state.no_magic_damage)
break;
- if(sc_data && sc_data[SC_DIVINA].timer != -1)
- skill_status_change_end(bl,SC_DIVINA,-1);
- else if( rand()%100 < sc_def_vit ) {
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
+ if (sc_data && sc_data[SC_DIVINA].timer != -1)
+ status_change_end(bl,SC_DIVINA, -1);
+ else if (rand() % 100 < sc_def_vit) {
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
}
}
break;
+
case SA_ABRACADABRA:
- //require 1 yellow gemstone even with mistress card or Into the Abyss
- if ((i=pc_search_inventory(sd, 715)) < 0 ) { //bug fixed by Lupus (item pos can be 0, too!)
- clif_skill_fail(sd,sd->skillid,0,0);
- break;
+ {
+ int abra_skillid = 0, abra_skilllv;
+ //require 1 yellow gemstone even with mistress card or Into the Abyss
+ if ((i = pc_search_inventory(sd, 715)) < 0 ) { //bug fixed by Lupus (item pos can be 0, too!)
+ clif_skill_fail(sd,sd->skillid,0,0);
+ break;
+ }
+ pc_delitem(sd, i, 1, 0);
+ do {
+ abra_skillid = rand() % 331;
+ if (skill_abra_db[abra_skillid].req_lv > skilllv ||
+ rand()%10000 >= skill_abra_db[abra_skillid].per || //db‚ÉŠî‚­ƒŒƒxƒ‹?Šm—¦”»’è
+ (abra_skillid >= NPC_PIERCINGATT && abra_skillid <= NPC_SUMMONMONSTER) || //NPCƒXƒLƒ‹‚̓_ƒ
+ skill_get_unit_flag(abra_skillid) & UF_DANCE) //‰‰‘tƒXƒLƒ‹‚̓_ƒ
+ abra_skillid = 0; // reset to get a new id
+ } while (abra_skillid == 0);
+ abra_skilllv = skill_get_max(abra_skillid) > skilllv ? skilllv : skill_get_max(abra_skillid);
+ clif_skill_nodamage (src, bl, skillid, skilllv, 1);
+ sd->skillitem = abra_skillid;
+ sd->skillitemlv = abra_skilllv;
+ clif_item_skill (sd, abra_skillid, abra_skilllv, "Abracadabra");
}
- //pc_delitem(sd, pc_search_inventory(sd, 715), 1, 0);
- pc_delitem(sd, i, 1, 0);
- //
- do{
- abra_skillid=skill_abra_dataset(skilllv);
- }while(abra_skillid == 0);
- abra_skilllv=skill_get_max(abra_skillid)>pc_checkskill(sd,SA_ABRACADABRA)?pc_checkskill(sd,SA_ABRACADABRA):skill_get_max(abra_skillid);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- sd->skillitem=abra_skillid;
- sd->skillitemlv=abra_skilllv;
- clif_item_skill(sd,abra_skillid,abra_skilllv,"ƒAƒuƒ‰ƒJƒ_ƒuƒ‰");
break;
+
case SA_COMA:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage )
- break;
- if(dstsd){
- dstsd->status.hp=1;
- dstsd->status.sp=1;
- clif_updatestatus(dstsd,SP_HP);
- clif_updatestatus(dstsd,SP_SP);
+ if (dstsd) {
+ if (dstsd->special_state.no_magic_damage)
+ break;
+ dstsd->status.hp = 1;
+ dstsd->status.sp = 1;
+ clif_updatestatus(dstsd, SP_HP);
+ clif_updatestatus(dstsd, SP_SP);
}
- if(dstmd) dstmd->hp=1;
+ if(dstmd) dstmd->hp = 1;
break;
case SA_FULLRECOVERY:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage )
- break;
- if(dstsd) pc_heal(dstsd,dstsd->status.max_hp,dstsd->status.max_sp);
- if(dstmd) dstmd->hp=battle_get_max_hp(&dstmd->bl);
+ if (dstsd) {
+ if (dstsd->special_state.no_magic_damage)
+ break;
+ pc_heal (dstsd, dstsd->status.max_hp, dstsd->status.max_sp);
+ }
+ if (dstmd) dstmd->hp = status_get_max_hp(bl);
break;
case SA_SUMMONMONSTER:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (sd) mob_once_spawn(sd,map[sd->bl.m].name,sd->bl.x,sd->bl.y,"--ja--",-1,1,"");
+ if (sd) mob_once_spawn(sd,map[src->m].name,src->x,src->y,"--ja--",-1,1,"");
break;
case SA_LEVELUP:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (sd && pc_nextbaseexp(sd)) pc_gainexp(sd,pc_nextbaseexp(sd)*10/100,0);
+ if (sd && pc_nextbaseexp(sd)) pc_gainexp(sd, pc_nextbaseexp(sd) * 10 / 100, 0);
break;
-
case SA_INSTANTDEATH:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
if (sd) pc_damage(NULL,sd,sd->status.max_hp);
break;
-
case SA_QUESTION:
case SA_GRAVITY:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
break;
case SA_CLASSCHANGE:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if(dstmd) mob_class_change(dstmd,changeclass);
+ {
+ //ƒNƒ‰ƒXƒ`ƒFƒ“ƒW—pƒ{ƒXƒ‚ƒ“ƒXƒ^?ID
+ int changeclass[]={1038,1039,1046,1059,1086,1087,1112,1115
+ ,1157,1159,1190,1272,1312,1373,1492};
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if(dstmd) mob_class_change(dstmd,changeclass);
+ }
break;
case SA_MONOCELL:
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if(dstmd) mob_class_change(dstmd,poringclass);
+ {
+ int poringclass[]={1002};
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if(dstmd) mob_class_change(dstmd,poringclass);
+ }
break;
case SA_DEATH:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
@@ -3041,19 +3000,20 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
break;
case SA_FORTUNE:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if(sd) pc_getzeny(sd,battle_get_lv(bl)*100);
+ if(sd) pc_getzeny(sd,status_get_lv(bl)*100);
break;
case SA_TAMINGMONSTER:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if (dstmd){
- for(i=0;i<MAX_PET_DB;i++){
- if(dstmd->class == pet_db[i].class){
- pet_catch_process1(sd,dstmd->class);
+ if (dstmd) {
+ for (i = 0; i < MAX_PET_DB; i++) {
+ if (dstmd->class_ == pet_db[i].class_) {
+ pet_catch_process1 (sd, dstmd->class_);
break;
}
}
}
break;
+
case AL_INCAGI: /* ‘¬“x?‰Á */
case AL_BLESSING: /* ƒuƒŒƒbƒVƒ“ƒO */
case PR_SLOWPOISON:
@@ -3062,38 +3022,37 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
case PR_SUFFRAGIUM: /* ƒTƒtƒ‰ƒMƒEƒ€ */
case PR_BENEDICTIO: /* ¹?~•Ÿ */
case CR_PROVIDENCE: /* ƒvƒƒ”ƒBƒfƒ“ƒX */
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage ){
+ if (dstsd && dstsd->special_state.no_magic_damage)
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- }else{
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ else {
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
clif_skill_nodamage(src,bl,skillid,skilllv,1);
}
break;
case CG_MARIONETTE: /* ƒ}ƒŠƒIƒlƒbƒgƒRƒ“ƒgƒ?ƒ‹ */
- if(sd && dstsd){
- struct status_change *sc_data = battle_get_sc_data(src);
- struct status_change *tsc_data = battle_get_sc_data(bl);
+ if (sd && dstsd){
+ struct status_change *sc_data = status_get_sc_data(src);
+ struct status_change *tsc_data = status_get_sc_data(bl);
int sc = SkillStatusChangeTable[skillid];
int sc2 = SC_MARIONETTE2;
-
- if((dstsd->bl.type!=BL_PC)
- || (sd->bl.id == dstsd->bl.id)
+
+ if ((sd == dstsd)
|| (!sd->status.party_id)
- || (sd->status.party_id != dstsd->status.party_id)) {
+ || (sd->status.party_id != dstsd->status.party_id)) {
clif_skill_fail(sd,skillid,0,0);
map_freeblock_unlock();
return 1;
}
if(sc_data && tsc_data){
- if(sc_data[sc].timer == -1 && tsc_data[sc2].timer == -1) {
- skill_status_change_start (src,sc,skilllv,0,bl->id,0,skill_get_time(skillid,skilllv),0);
- skill_status_change_start (bl,sc2,skilllv,0,src->id,0,skill_get_time(skillid,skilllv),0);
+ if (sc_data[sc].timer == -1 && tsc_data[sc2].timer == -1) {
+ status_change_start (src,sc,skilllv,0,bl->id,0,skill_get_time(skillid,skilllv),0);
+ status_change_start (bl,sc2,skilllv,0,src->id,0,skill_get_time(skillid,skilllv),0);
}
else if (sc_data[sc].timer != -1 && tsc_data[sc2].timer != -1 &&
- sc_data[sc].val3 == bl->id && tsc_data[sc2].val3 == src->id) {
- skill_status_change_end(src, sc, -1);
- skill_status_change_end(bl, sc2, -1);
+ sc_data[sc].val3 == bl->id && tsc_data[sc2].val3 == src->id) {
+ status_change_end(src, sc, -1);
+ status_change_end(bl, sc2, -1);
}
else {
clif_skill_fail(sd,skillid,0,0);
@@ -3102,57 +3061,60 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
}
clif_skill_nodamage(src,bl,skillid,skilllv,1);
}
- }
+ }
break;
case SA_FLAMELAUNCHER: // added failure chance and chance to break weapon if turned on [Valaris]
case SA_FROSTWEAPON:
case SA_LIGHTNINGLOADER:
case SA_SEISMICWEAPON:
- if(bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage ){
- clif_skill_nodamage(src,bl,skillid,skilllv,0);
- break;
- }
- if(bl->type==BL_PC) {
- struct map_session_data *sd2=(struct map_session_data *)bl;
- if(sd2->status.weapon==0 || sd2->sc_data[SC_FLAMELAUNCHER].timer!=-1 || sd2->sc_data[SC_FROSTWEAPON].timer!=-1 ||
- sd2->sc_data[SC_LIGHTNINGLOADER].timer!=-1 || sd2->sc_data[SC_SEISMICWEAPON].timer!=-1 ||
- sd2->sc_data[SC_ENCPOISON].timer!=-1) {
- clif_skill_fail(sd,skillid,0,0);
+ if (dstsd) {
+ if (dstsd->special_state.no_magic_damage) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,0);
+ break;
+ }
+ if(dstsd->status.weapon == 0 ||
+ (sd && sd->status.party_id > 0 && sd->status.party_id != dstsd->status.party_id) ||
+ dstsd->sc_data[SC_FLAMELAUNCHER].timer != -1 ||
+ dstsd->sc_data[SC_FROSTWEAPON].timer != -1 ||
+ dstsd->sc_data[SC_LIGHTNINGLOADER].timer != -1 ||
+ dstsd->sc_data[SC_SEISMICWEAPON].timer != -1 ||
+ dstsd->sc_data[SC_ENCPOISON].timer != -1) {
+ if (sd) clif_skill_fail(sd,skillid,0,0);
clif_skill_nodamage(src,bl,skillid,skilllv,0);
break;
}
}
- if(rand()%100 > (75+skilllv*1) && (skilllv != 5)) {
- clif_skill_fail(sd,skillid,0,0);
+ if(skilllv < 5 && rand()%100 > (60+skilllv*10) ) { //fixed by Lupus (4 -> 5) or else it has 100% success even at lv4
+ if (sd) clif_skill_fail(sd,skillid,0,0);
clif_skill_nodamage(src,bl,skillid,skilllv,0);
- if(bl->type==BL_PC && battle_config.equipment_breaking) {
- struct map_session_data *sd2=(struct map_session_data *)bl;
- if(sd!=sd2) clif_displaymessage(sd->fd,"You broke target's weapon");
- pc_breakweapon(sd2);
+ if(dstsd && battle_config.equipment_breaking) {
+ if(sd && sd != dstsd) clif_displaymessage(sd->fd,"You broke target's weapon");
+ pc_breakweapon(dstsd);
}
break;
- }
- else {
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ } else {
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
clif_skill_nodamage(src,bl,skillid,skilllv,1);
}
break;
case PR_ASPERSIO: /* ƒAƒXƒyƒ‹ƒVƒI */
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage )
+ if (dstsd && dstsd->special_state.no_magic_damage)
break;
- if(bl->type==BL_MOB)
+ if (dstmd)
break;
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
break;
+
case PR_KYRIE: /* ƒLƒŠƒGƒGƒŒƒCƒ\ƒ“ */
clif_skill_nodamage(bl,bl,skillid,skilllv,1);
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage )
+ if (dstsd && dstsd->special_state.no_magic_damage)
break;
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
break;
+
case KN_AUTOCOUNTER: /* ƒI?ƒgƒJƒEƒ“ƒ^? */
case KN_TWOHANDQUICKEN: /* ƒc?ƒnƒ“ƒhƒNƒCƒbƒPƒ“ */
case CR_SPEARQUICKEN: /* ƒXƒsƒAƒNƒCƒbƒPƒ“ */
@@ -3176,68 +3138,87 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
case ST_REJECTSWORD: /* ƒŠƒWƒFƒNƒgƒ\?ƒh */
case HW_MAGICPOWER: /* –‚–@—Í?• */
case PF_MEMORIZE: /* ƒƒ‚ƒ‰ƒCƒY */
+ case PA_SACRIFICE:
case ASC_EDP: // [Celest]
+ case CG_MOONLIT: /* ŒŽ–¾‚è‚Ìò‚É—Ž‚¿‚é‰Ô‚Ñ‚ç */
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
break;
+
case SM_ENDURE: /* ƒCƒ“ƒfƒ…ƒA */
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
- skill_status_change_start(src,SC_BLOCKSKILL,skilllv,0,skillid,0,10000,0 );
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ if (sd)
+ pc_blockskill_start (sd, skillid, 10000);
break;
-
-
+
+ case SM_AUTOBERSERK: // Celest
+ {
+ struct status_change *tsc_data = status_get_sc_data(bl);
+ int sc = SkillStatusChangeTable[skillid];
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if (tsc_data && tsc_data[sc].timer != -1)
+ status_change_end(bl, sc, -1);
+ else
+ status_change_start(bl,sc,skilllv,0,0,0,0,0);
+ }
+ break;
+
case AS_ENCHANTPOISON: // Prevent spamming [Valaris]
- if(bl->type==BL_PC) {
- struct map_session_data *sd2=(struct map_session_data *)bl;
- if(sd2->sc_data[SC_FLAMELAUNCHER].timer!=-1 || sd2->sc_data[SC_FROSTWEAPON].timer!=-1 ||
- sd2->sc_data[SC_LIGHTNINGLOADER].timer!=-1 || sd2->sc_data[SC_SEISMICWEAPON].timer!=-1 ||
- sd2->sc_data[SC_ENCPOISON].timer!=-1) {
- clif_skill_nodamage(src,bl,skillid,skilllv,0);
- clif_skill_fail(sd,skillid,0,0);
- break;
+ if (dstsd) {
+ if(dstsd->sc_data[SC_FLAMELAUNCHER].timer != -1 ||
+ dstsd->sc_data[SC_FROSTWEAPON].timer != -1 ||
+ dstsd->sc_data[SC_LIGHTNINGLOADER].timer != -1 ||
+ dstsd->sc_data[SC_SEISMICWEAPON].timer != -1 ||
+ dstsd->sc_data[SC_ENCPOISON].timer != -1) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,0);
+ clif_skill_fail(sd,skillid,0,0);
+ break;
}
}
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
break;
+
case LK_TENSIONRELAX: /* ƒeƒ“ƒVƒ‡ƒ“ƒŠƒ‰ƒbƒNƒX */
clif_skill_nodamage(src,bl,skillid,skilllv,1);
pc_setsit(sd);
clif_sitting(sd);
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
break;
case LK_BERSERK: /* ƒo?ƒT?ƒN */
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
//sd->status.hp = sd->status.max_hp * 3;
break;
+
case MC_CHANGECART:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
break;
+
case AC_CONCENTRATION: /* W’†—ÍŒüã */
{
int range = 1;
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
- map_foreachinarea( skill_status_change_timer_sub,
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ map_foreachinarea( status_change_timer_sub,
src->m, src->x-range, src->y-range, src->x+range,src->y+range,0,
src,SkillStatusChangeTable[skillid],tick);
}
break;
+
case SM_PROVOKE: /* ƒvƒƒ{ƒbƒN */
{
- struct status_change *sc_data = battle_get_sc_data(bl);
+ struct status_change *sc_data = status_get_sc_data(bl);
/* MVPmob‚Æ•sŽ€‚É‚Í?‚©‚È‚¢ */
- if((bl->type==BL_MOB && battle_get_mode(bl)&0x20) || battle_check_undead(battle_get_race(bl),battle_get_elem_type(bl))) //•sŽ€‚É‚Í?‚©‚È‚¢
- {
+ if((dstmd && status_get_mode(bl)&0x20) || battle_check_undead(status_get_race(bl),status_get_elem_type(bl))) { //•sŽ€‚É‚Í?‚©‚È‚¢
map_freeblock_unlock();
return 1;
}
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
if(dstmd && dstmd->skilltimer!=-1 && dstmd->state.skillcastcancel) // ‰r¥–WŠQ
skill_castcancel(bl,0);
@@ -3247,18 +3228,17 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
if(sc_data){
if(sc_data[SC_FREEZE].timer!=-1)
- skill_status_change_end(bl,SC_FREEZE,-1);
+ status_change_end(bl,SC_FREEZE,-1);
if(sc_data[SC_STONE].timer!=-1 && sc_data[SC_STONE].val2==0)
- skill_status_change_end(bl,SC_STONE,-1);
+ status_change_end(bl,SC_STONE,-1);
if(sc_data[SC_SLEEP].timer!=-1)
- skill_status_change_end(bl,SC_SLEEP,-1);
+ status_change_end(bl,SC_SLEEP,-1);
}
- if(bl->type==BL_MOB) {
+ if(dstmd) {
int range = skill_get_range(skillid,skilllv);
- if(range < 0)
- range = battle_get_range(src) - (range + 1);
- mob_target((struct mob_data *)bl,src,range);
+ dstmd->state.provoke_flag = src->id;
+ mob_target(dstmd,src,range);
}
}
break;
@@ -3266,27 +3246,27 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
case CR_DEVOTION: /* ƒfƒBƒ{?ƒVƒ‡ƒ“ */
if(sd && dstsd){
//?¶‚â—{Žq‚Ìꇂ̌³‚ÌE‹Æ‚ðŽZo‚·‚é
- struct pc_base_job dst_s_class = pc_calc_base_job(dstsd->status.class);
-
- int lv = sd->status.base_level-dstsd->status.base_level;
- lv = (lv<0)?-lv:lv;
- if((dstsd->bl.type!=BL_PC) // ‘ŠŽè‚ÍPC‚¶‚á‚È‚¢‚Æ‚¾‚ß
- ||(sd->bl.id == dstsd->bl.id) // ‘ŠŽè‚ªŽ©•ª‚Í‚¾‚ß
- ||(lv > 10) // ƒŒƒxƒ‹·}10‚Ü‚Å
- ||(!sd->status.party_id && !sd->status.guild_id) // PT‚É‚àƒMƒ‹ƒh‚É‚àŠ?–³‚µ‚Í‚¾‚ß
- ||((sd->status.party_id != dstsd->status.party_id) // “¯‚¶ƒp?ƒeƒB?‚©A
- &&(sd->status.guild_id != dstsd->status.guild_id)) // “¯‚¶ƒMƒ‹ƒh‚¶‚á‚È‚¢‚Æ‚¾‚ß
- ||(dst_s_class.job==14||dst_s_class.job==21)){ // ƒNƒ‹ƒZ‚¾‚ß
+ int s_class = pc_calc_base_job2 (dstsd->status.class_);
+
+ int lv = sd->status.base_level - dstsd->status.base_level;
+ if (lv < 0) lv = -lv;
+ if ((sd == dstsd) // ‘ŠŽè‚ÍPC‚¶‚á‚È‚¢‚Æ‚¾‚ß
+ || (sd->bl.id == dstsd->bl.id) // ‘ŠŽè‚ªŽ©•ª‚Í‚¾‚ß
+ || (lv > battle_config.devotion_level_difference) // ƒŒƒxƒ‹·}10‚Ü‚Å
+ || (!sd->status.party_id && !sd->status.guild_id) // PT‚É‚àƒMƒ‹ƒh‚É‚àŠ?–³‚µ‚Í‚¾‚ß
+ || ((sd->status.party_id != dstsd->status.party_id) // “¯‚¶ƒp?ƒeƒB?‚©A
+ &&(sd->status.guild_id != dstsd->status.guild_id)) // “¯‚¶ƒMƒ‹ƒh‚¶‚á‚È‚¢‚Æ‚¾‚ß
+ || (s_class == 14 || s_class == 21)) { // ƒNƒ‹ƒZ‚¾‚ß
clif_skill_fail(sd,skillid,0,0);
map_freeblock_unlock();
return 1;
}
- for(i=0;i<skilllv;i++){
- if(!sd->dev.val1[i]){ // ‹ó‚«‚ª‚ ‚Á‚½‚ç“ü‚ê‚é
+ for (i = 0; i < skilllv; i++) {
+ if (!sd->dev.val1[i]) { // ‹ó‚«‚ª‚ ‚Á‚½‚ç“ü‚ê‚é
sd->dev.val1[i] = bl->id;
sd->dev.val2[i] = bl->id;
break;
- }else if(i==skilllv-1){ // ‹ó‚«‚ª‚È‚©‚Á‚½
+ } else if (i == skilllv - 1) { // ‹ó‚«‚ª‚È‚©‚Á‚½
clif_skill_fail(sd,skillid,0,0);
map_freeblock_unlock();
return 1;
@@ -3294,54 +3274,56 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
}
clif_skill_nodamage(src,bl,skillid,skilllv,1);
clif_devotion(sd,bl->id);
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],src->id,1,0,0,1000*(15+15*skilllv),0 );
+ status_change_start(bl,SkillStatusChangeTable[skillid],src->id,1,0,0,1000*(15+15*skilllv),0 );
}
- else clif_skill_fail(sd,skillid,0,0);
+ else clif_skill_fail(sd,skillid,0,0);
break;
+
case MO_CALLSPIRITS: // ?Œ÷
if(sd) {
clif_skill_nodamage(src,bl,skillid,skilllv,1);
pc_addspiritball(sd,skill_get_time(skillid,skilllv),skilllv);
}
break;
+
case CH_SOULCOLLECT: // ‹¶?Œ÷
if(sd) {
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- for(i=0;i<5;i++)
+ for (i = 0; i < 5; i++)
pc_addspiritball(sd,skill_get_time(skillid,skilllv),5);
}
break;
+
case MO_BLADESTOP: // ”’nŽæ‚è
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_status_change_start(src,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ status_change_start(src,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
break;
+
case MO_ABSORBSPIRITS: // ?’D
i=0;
- if(sd && dstsd) {
- if(sd == dstsd || map[sd->bl.m].flag.pvp || map[sd->bl.m].flag.gvg) {
- if(dstsd->spiritball > 0) {
+ if (dstsd) {
+ if ((sd && sd == dstsd) || map[src->m].flag.pvp || map[src->m].flag.gvg) {
+ if (dstsd->spiritball > 0) {
clif_skill_nodamage(src,bl,skillid,skilllv,1);
i = dstsd->spiritball * 7;
pc_delspiritball(dstsd,dstsd->spiritball,0);
if(i > 0x7FFF)
i = 0x7FFF;
- if(sd->status.sp + i > sd->status.max_sp)
+ if(sd && sd->status.sp + i > sd->status.max_sp)
i = sd->status.max_sp - sd->status.sp;
- }
+ }
}
- }else if(sd && dstmd){ //?Û‚ªƒ‚ƒ“ƒXƒ^?‚Ìê‡
+ } else if (dstmd) { //?Û‚ªƒ‚ƒ“ƒXƒ^?‚Ìê‡
//20%‚ÌŠm—¦‚Å?Û‚ÌLv*2‚ÌSP‚ð‰ñ•œ‚·‚éB¬Œ÷‚µ‚½‚Æ‚«‚̓^?ƒQƒbƒg(ƒÐ?„D?)ƒÐ????!!
- if(rand()%100<20){
- i=2*mob_db[dstmd->class].lv;
+ if(rand() % 100 < 20) {
+ i = 2 * mob_db[dstmd->class_].lv;
mob_target(dstmd,src,0);
}
}
- if(i){
- sd->status.sp += i;
- clif_heal(sd->fd,SP_SP,i);
- }
- else
- clif_skill_nodamage(src,bl,skillid,skilllv,0);
+ if (i && sd){
+ sd->status.sp += i;
+ clif_heal(sd->fd,SP_SP,i);
+ } else clif_skill_nodamage(src,bl,skillid,skilllv,0);
break;
case AC_MAKINGARROW: /* –îì¬ */
@@ -3375,29 +3357,30 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
clif_skill_produce_mix_list(sd,256);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
}
- break;
+ break;
case BS_HAMMERFALL: /* ƒnƒ“ƒ}?ƒtƒH?ƒ‹ */
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_weapon_damage )
+ if(dstsd && dstsd->special_state.no_weapon_damage)
break;
- if( rand()%100 < (20+ 10*skilllv)*sc_def_vit/100 ) {
- skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
- }
+ if(rand() % 100 < (20 + 10 * skilllv) * sc_def_vit / 100 )
+ status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case RG_RAID: /* ƒTƒvƒ‰ƒCƒYƒAƒ^ƒbƒN */
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- {
- int x=bl->x,y=bl->y;
- skill_area_temp[1]=bl->id;
- skill_area_temp[2]=x;
- skill_area_temp[3]=y;
- map_foreachinarea(skill_area_sub,
- bl->m,x-1,y-1,x+1,y+1,0,
- src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
- skill_castend_damage_id);
- }
- skill_status_change_end(src, SC_HIDING, -1); // ƒnƒCƒfƒBƒ“ƒO‰ðœ
+ map_foreachinarea(skill_area_sub,
+ bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,0,
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
+ skill_castend_damage_id);
+ status_change_end(src, SC_HIDING, -1); // ƒnƒCƒfƒBƒ“ƒO‰ðœ
+ break;
+
+ case ASC_METEORASSAULT: /* ƒƒeƒIƒAƒTƒ‹ƒg */
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ map_foreachinarea(skill_area_sub,
+ bl->m,bl->x-2,bl->y-2,bl->x+2,bl->y+2,0,
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
+ skill_castend_damage_id);
break;
case KN_BRANDISHSPEAR: /*ƒuƒ‰ƒ“ƒfƒBƒbƒVƒ…ƒXƒsƒA*/
@@ -3455,30 +3438,29 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
case PR_MAGNIFICAT: /* ƒ}ƒOƒjƒtƒBƒJ?ƒg */
case PR_GLORIA: /* ƒOƒƒŠƒA */
case SN_WINDWALK: /* ƒEƒCƒ“ƒhƒEƒH?ƒN */
- if(sd == NULL || sd->status.party_id==0 || (flag&1) ){
+ if (sd == NULL || sd->status.party_id == 0 || (flag & 1)) {
/* ŒÂ•Ê‚Ì?— */
clif_skill_nodamage(bl,bl,skillid,skilllv,1);
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage )
+ if(dstsd && dstsd->special_state.no_magic_damage)
break;
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
- }
- else{
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
+ } else if (sd) {
/* ƒp?ƒeƒB‘S?‚Ö‚Ì?— */
- party_foreachsamemap(skill_area_sub,
+ party_foreachsamemap (skill_area_sub,
sd,1,
src,skillid,skilllv,tick, flag|BCT_PARTY|1,
skill_castend_nodamage_id);
}
break;
+
case BS_ADRENALINE: /* ƒAƒhƒŒƒiƒŠƒ“ƒ‰ƒbƒVƒ… */
case BS_WEAPONPERFECT: /* ƒEƒFƒ|ƒ“ƒp?ƒtƒFƒNƒVƒ‡ƒ“ */
case BS_OVERTHRUST: /* ƒI?ƒo?ƒgƒ‰ƒXƒg */
- if(sd == NULL || sd->status.party_id==0 || (flag&1) ){
+ if (sd == NULL || sd->status.party_id == 0 || (flag & 1)) {
/* ŒÂ•Ê‚Ì?— */
clif_skill_nodamage(bl,bl,skillid,skilllv,1);
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,(src == bl)? 1:0,0,0,skill_get_time(skillid,skilllv),0);
- }
- else{
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,(src == bl)? 1:0,0,0,skill_get_time(skillid,skilllv),0);
+ } else if (sd) {
/* ƒp?ƒeƒB‘S?‚Ö‚Ì?— */
party_foreachsamemap(skill_area_sub,
sd,1,
@@ -3493,66 +3475,54 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
case CR_DEFENDER: /* ƒfƒBƒtƒFƒ“ƒ_? */
case CR_AUTOGUARD: /* ƒI?ƒgƒK?ƒh */
{
- struct status_change *tsc_data = battle_get_sc_data(bl);
- int sc=SkillStatusChangeTable[skillid];
+ struct status_change *tsc_data = status_get_sc_data(bl);
+ int sc = SkillStatusChangeTable[skillid];
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if( tsc_data ){
- if( tsc_data[sc].timer==-1 )
- /* •t‰Á‚·‚é */
- skill_status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
- else
- /* ‰ðœ‚·‚é */
- skill_status_change_end(bl, sc, -1);
- }
+ if (tsc_data && tsc_data[sc].timer != -1)
+ status_change_end(bl, sc, -1);
+ else
+ status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
}
break;
case TF_HIDING: /* ƒnƒCƒfƒBƒ“ƒO */
{
- struct status_change *tsc_data = battle_get_sc_data(bl);
- int sc=SkillStatusChangeTable[skillid];
+ struct status_change *tsc_data = status_get_sc_data(bl);
+ int sc = SkillStatusChangeTable[skillid];
clif_skill_nodamage(src,bl,skillid,-1,1);
- if( tsc_data ){
- if( tsc_data[sc].timer==-1 )
- /* •t‰Á‚·‚é */
- skill_status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
+ if (tsc_data && tsc_data[sc].timer != -1)
+ status_change_end(bl, sc, -1);
else
- /* ‰ðœ‚·‚é */
- skill_status_change_end(bl, sc, -1);
- }
+ status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
}
break;
case AS_CLOAKING: /* ƒNƒ?ƒLƒ“ƒO */
{
- struct status_change *tsc_data = battle_get_sc_data(bl);
+ struct status_change *tsc_data = status_get_sc_data(bl);
int sc=SkillStatusChangeTable[skillid];
clif_skill_nodamage(src,bl,skillid,-1,1);
- if( tsc_data ){
- if( tsc_data[sc].timer==-1 )
- /* •t‰Á‚·‚é */
- skill_status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
- else
+ if(tsc_data && tsc_data[sc].timer!=-1 )
/* ‰ðœ‚·‚é */
- skill_status_change_end(bl, sc, -1);
- }
+ status_change_end(bl, sc, -1);
+ else
+ /* •t‰Á‚·‚é */
+ status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
//skill_check_cloaking(bl);
}
break;
case ST_CHASEWALK: /* ƒnƒCƒfƒBƒ“ƒO */
{
- struct status_change *tsc_data = battle_get_sc_data(bl);
+ struct status_change *tsc_data = status_get_sc_data(bl);
int sc=SkillStatusChangeTable[skillid];
clif_skill_nodamage(src,bl,skillid,-1,1);
- if( tsc_data ){
- if( tsc_data[sc].timer==-1 )
- /* •t‰Á‚·‚é */
- skill_status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
- else
+ if(tsc_data && tsc_data[sc].timer!=-1 )
/* ‰ðœ‚·‚é */
- skill_status_change_end(bl, sc, -1);
- }
+ status_change_end(bl, sc, -1);
+ else
+ /* •t‰Á‚·‚é */
+ status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
}
break;
@@ -3575,32 +3545,20 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
case DC_DONTFORGETME: /* Ž„‚ð–Y‚ê‚È‚¢‚Åc */
case DC_FORTUNEKISS: /* K‰^‚̃LƒX */
case DC_SERVICEFORYOU: /* ƒT?ƒrƒXƒtƒH?ƒ†? */
- case CG_MOONLIT: /* ŒŽ–¾‚è‚Ìò‚É—Ž‚¿‚é‰Ô‚Ñ‚ç */
+// case CG_MOONLIT: /* ŒŽ–¾‚è‚Ìò‚É—Ž‚¿‚é‰Ô‚Ñ‚ç */
clif_skill_nodamage(src,bl,skillid,skilllv,1);
skill_unitsetting(src,skillid,skilllv,src->x,src->y,0);
break;
case HP_BASILICA: /* ƒoƒWƒŠƒJ */
{
- // cancel Basilica if already in effect
- struct status_change *sc_data = battle_get_sc_data(src);
- if(sc_data && sc_data[SC_BASILICA].timer != -1){
- struct skill_unit *su;
- if ((su = (struct skill_unit *)sc_data[SC_BASILICA].val4)) {
- struct skill_unit_group *sg;
- if ((sg = su->group) && sg->src_id == sd->bl.id) {
- skill_status_change_end(src,SC_BASILICA,-1);
- skill_delunitgroup (sg);
- break;
- }
- }
- } else {
- // otherwise allow casting
- skill_status_change_start(src,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
- skill_clear_unitgroup(src);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_unitsetting(src,skillid,skilllv,src->x,src->y,0);
- }
+ struct skill_unit_group *sg;
+ battle_stopwalking(src,1);
+ skill_clear_unitgroup(src);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ sg = skill_unitsetting(src,skillid,skilllv,src->x,src->y,0);
+ status_change_start(src,SkillStatusChangeTable[skillid],skilllv,0,0,(int)sg,
+ skill_get_time(skillid,skilllv),0);
}
break;
@@ -3608,11 +3566,12 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
skill_clear_unitgroup(src);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
skill_unitsetting(src,skillid,skilllv,src->x,src->y,0);
+ status_change_start(src,SkillStatusChangeTable[skillid],skilllv,0,0,BCT_SELF,skill_get_time(skillid,skilllv),0);
break;
case BD_ADAPTATION: /* ƒAƒhƒŠƒu */
{
- struct status_change *sc_data = battle_get_sc_data(src);
+ struct status_change *sc_data = status_get_sc_data(src);
if(sc_data && sc_data[SC_DANCING].timer!=-1){
clif_skill_nodamage(src,bl,skillid,skilllv,1);
skill_stop_dancing(src,0);
@@ -3636,11 +3595,11 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
break;
case RG_STEALCOIN: // ƒXƒeƒB?ƒ‹ƒRƒCƒ“
- if(sd) {
+ if(sd) {
if(pc_steal_coin(sd,bl)) {
int range = skill_get_range(skillid,skilllv);
if(range < 0)
- range = battle_get_range(src) - (range + 1);
+ range = status_get_range(src) - (range + 1);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
mob_target((struct mob_data *)bl,src,range);
}
@@ -3650,17 +3609,41 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
break;
case MG_STONECURSE: /* ƒXƒg?ƒ“ƒJ?ƒX */
- if (bl->type==BL_MOB && battle_get_mode(bl)&0x20) {
- clif_skill_fail(sd,sd->skillid,0,0);
- break;
+ {
+ struct status_change *sc_data = status_get_sc_data(bl);
+ // Level 6-10 doesn't consume a red gem if it fails [celest]
+ int i, gem_flag = 1, fail_flag = 0;
+ if (dstmd && status_get_mode(bl)&0x20) {
+ clif_skill_fail(sd,sd->skillid,0,0);
+ break;
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if(dstsd && dstsd->special_state.no_magic_damage )
+ break;
+ if (sc_data && sc_data[SC_STONE].timer != -1) {
+ status_change_end(bl,SC_STONE,-1);
+ if (sd) {
+ fail_flag = 1;
+ clif_skill_fail(sd,skillid,0,0);
+ }
+ }
+ else if( rand()%100 < skilllv*4+20 && !battle_check_undead(status_get_race(bl),status_get_elem_type(bl)))
+ status_change_start(bl,SC_STONE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ else if(sd) {
+ if (skilllv > 5) gem_flag = 0;
+ clif_skill_fail(sd,skillid,0,0);
+ fail_flag = 1;
+ }
+ if (dstmd)
+ mob_target(dstmd,src,skill_get_range(skillid,skilllv));
+ if (sd && gem_flag) {
+ if ((i=pc_search_inventory(sd, skill_db[skillid].itemid[0])) < 0 ) {
+ if (!fail_flag) clif_skill_fail(sd,sd->skillid,0,0);
+ break;
+ }
+ pc_delitem(sd, i, skill_db[skillid].amount[0], 0);
+ }
}
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage )
- break;
- if( rand()%100 < skilllv*4+20 && !battle_check_undead(battle_get_race(bl),battle_get_elem_type(bl)))
- skill_status_change_start(bl,SC_STONE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
- else if(sd)
- clif_skill_fail(sd,skillid,0,0);
break;
case NV_FIRSTAID: /* ?‹}Žè? */
@@ -3670,37 +3653,36 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
case AL_CURE: /* ƒLƒ…ƒA? */
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage )
+ if(dstsd && dstsd->special_state.no_magic_damage )
break;
- skill_status_change_end(bl, SC_SILENCE , -1 );
- skill_status_change_end(bl, SC_BLIND , -1 );
- skill_status_change_end(bl, SC_CONFUSION, -1 );
- if( battle_check_undead(battle_get_race(bl),battle_get_elem_type(bl)) ){//ƒAƒ“ƒfƒbƒh‚È‚çˆÃˆÅ?‰Ê
- skill_status_change_start(bl, SC_CONFUSION,1,0,0,0,6000,0);
+ status_change_end(bl, SC_SILENCE , -1 );
+ status_change_end(bl, SC_BLIND , -1 );
+ status_change_end(bl, SC_CONFUSION, -1 );
+ if( battle_check_undead(status_get_race(bl),status_get_elem_type(bl)) ){//ƒAƒ“ƒfƒbƒh‚È‚çˆÃˆÅ?‰Ê
+ status_change_start(bl, SC_CONFUSION,1,0,0,0,6000,0);
}
break;
case TF_DETOXIFY: /* ‰ð“Å */
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_status_change_end(bl, SC_POISON , -1 );
- skill_status_change_end(bl, SC_DPOISON , -1 );
+ status_change_end(bl, SC_POISON , -1 );
+ status_change_end(bl, SC_DPOISON , -1 );
break;
case PR_STRECOVERY: /* ƒŠƒJƒoƒŠ? */
{
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage )
+ if(dstsd && dstsd->special_state.no_magic_damage)
break;
- skill_status_change_end(bl, SC_FREEZE , -1 );
- skill_status_change_end(bl, SC_STONE , -1 );
- skill_status_change_end(bl, SC_SLEEP , -1 );
- skill_status_change_end(bl, SC_STAN , -1 );
- if( battle_check_undead(battle_get_race(bl),battle_get_elem_type(bl)) ){//ƒAƒ“ƒfƒbƒh‚È‚çˆÃˆÅ?‰Ê
- int blind_time;
- //blind_time=30-battle_get_vit(bl)/10-battle_get_int/15;
- blind_time=30*(100-(battle_get_int(bl)+battle_get_vit(bl))/2)/100;
- if(rand()%100 < (100-(battle_get_int(bl)/2+battle_get_vit(bl)/3+battle_get_luk(bl)/10)))
- skill_status_change_start(bl, SC_BLIND,1,0,0,0,blind_time,0);
+ status_change_end(bl, SC_FREEZE , -1 );
+ status_change_end(bl, SC_STONE , -1 );
+ status_change_end(bl, SC_SLEEP , -1 );
+ status_change_end(bl, SC_STAN , -1 );
+ if( battle_check_undead(status_get_race(bl),status_get_elem_type(bl)) ){//ƒAƒ“ƒfƒbƒh‚È‚çˆÃˆÅ?‰Ê
+ if(rand()%100 < (100-(status_get_int(bl)/2+status_get_vit(bl)/3+status_get_luk(bl)/10))) {
+ status_change_start(bl, SC_BLIND,1,0,0,0,
+ 1000 * 30 * (100-(status_get_int(bl)+status_get_vit(bl))/2)/100,0);
+ }
}
if(dstmd){
dstmd->attacked_id=0;
@@ -3713,7 +3695,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
break;
case WZ_ESTIMATION: /* ƒ‚ƒ“ƒXƒ^?î•ñ */
- if(src->type==BL_PC){
+ if(sd) {
clif_skill_nodamage(src,bl,skillid,skilllv,1);
clif_skill_estimation((struct map_session_data *)src,bl);
}
@@ -3727,11 +3709,11 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
case BS_REPAIRWEAPON: /* •ŠíC— */
if(sd) {
//“®ì‚µ‚È‚¢‚̂łƂ肠‚¦‚¸ƒRƒƒ“ƒgƒAƒEƒg
- if (pc_search_inventory(sd, 999) < 0 ) { //fixed by Lupus (item pos can be = 0!)
+ /*if (pc_search_inventory(sd, 999) < 0 ) { //fixed by Lupus (item pos can be = 0!)
clif_skill_fail(sd,sd->skillid,0,0);
map_freeblock_unlock();
return 1;
- }
+ }*/
clif_item_repair_list(sd);
}
break;
@@ -3742,20 +3724,20 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
break;
case AL_TELEPORT: /* ƒeƒŒƒ|?ƒg */
- if( sd ){
- if(map[sd->bl.m].flag.noteleport){ /* ƒeƒŒƒ|‹ÖŽ~ */
+ if(sd) {
+ if (map[sd->bl.m].flag.noteleport) { /* ƒeƒŒƒ|‹ÖŽ~ */
clif_skill_teleportmessage(sd,0);
break;
}
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if( sd->skilllv==1 )
+ if(sd->skilllv == 1)
clif_skill_warppoint(sd,sd->skillid,"Random","","","");
- else{
+ else {
clif_skill_warppoint(sd,sd->skillid,"Random",
sd->status.save_point.map,"","");
}
- }else if( bl->type==BL_MOB )
- mob_warp((struct mob_data *)bl,-1,-1,-1,3);
+ } else if(dstmd)
+ mob_warp(dstmd,-1,-1,-1,3);
break;
case AL_HOLYWATER: /* ƒAƒNƒAƒxƒlƒfƒBƒNƒ^ */
@@ -3799,136 +3781,102 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
break;
case RG_STRIPWEAPON: /* ƒXƒgƒŠƒbƒvƒEƒFƒ|ƒ“ */
- {
- struct status_change *tsc_data = battle_get_sc_data(bl);
-
- if(tsc_data && tsc_data[SC_CP_WEAPON].timer != -1 )
+ case RG_STRIPSHIELD: /* ƒXƒgƒŠƒbƒvƒV[ƒ‹ƒh */
+ case RG_STRIPARMOR: /* ƒXƒgƒŠƒbƒvƒA[ƒ}[ */
+ case RG_STRIPHELM: /* ƒXƒgƒŠƒbƒvƒwƒ‹ƒ€ */
+ {
+ struct status_change *tsc_data;
+ int strip_time, strip_per, strip_fix;
+ int scid, cp_scid = 0, equip;
+
+ tsc_data = status_get_sc_data(bl);
+ scid = SkillStatusChangeTable[skillid];
+ switch (skillid) {
+ case RG_STRIPWEAPON:
+ equip = EQP_WEAPON;
+ cp_scid = SC_CP_WEAPON;
break;
- strip_per = 5+2*skilllv+strip_fix/5;
- strip_time = skill_get_time(skillid,skilllv)+strip_fix/2;
- if(rand()%100 < strip_per){
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,strip_time,0 );
- if(dstsd){
- for(i=0;i<MAX_INVENTORY;i++){
- if(dstsd->status.inventory[i].equip && dstsd->status.inventory[i].equip & 0x0002){
- pc_unequipitem(dstsd,i,0,BF_SKILL);
- break;
- }
- }
- }
- }
- }
- break;
-
- case RG_STRIPSHIELD: /* ƒXƒgƒŠƒbƒvƒV?ƒ‹ƒh */
- {
- struct status_change *tsc_data = battle_get_sc_data(bl);
-
- if(tsc_data && tsc_data[SC_CP_SHIELD].timer != -1 )
+ case RG_STRIPSHIELD:
+ equip = EQP_SHIELD;
+ cp_scid = SC_CP_SHIELD;
break;
- strip_per = 5+2*skilllv+strip_fix/5;
- strip_time = skill_get_time(skillid,skilllv)+strip_fix/2;
- if(rand()%100 < strip_per){
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,strip_time,0 );
- if(dstsd){
- for(i=0;i<MAX_INVENTORY;i++){
- if(dstsd->status.inventory[i].equip && dstsd->status.inventory[i].equip & 0x0020){
- pc_unequipitem(dstsd,i,0,BF_SKILL);
- break;
- }
- }
- }
- }
- }
- break;
-
- case RG_STRIPARMOR: /* ƒXƒgƒŠƒbƒvƒA?ƒ}? */
- {
- struct status_change *tsc_data = battle_get_sc_data(bl);
-
- if(tsc_data && tsc_data[SC_CP_ARMOR].timer != -1 )
+ case RG_STRIPARMOR:
+ equip = EQP_ARMOR;
+ cp_scid = SC_CP_ARMOR;
break;
- strip_per = 5+2*skilllv+strip_fix/5;
- strip_time = skill_get_time(skillid,skilllv)+strip_fix/2;
- if(rand()%100 < strip_per){
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,strip_time,0 );
- if(dstsd){
- for(i=0;i<MAX_INVENTORY;i++){
- if(dstsd->status.inventory[i].equip && dstsd->status.inventory[i].equip & 0x0010){
- pc_unequipitem(dstsd,i,0,BF_SKILL);
- break;
- }
- }
- }
- }
- }
- break;
-
- case RG_STRIPHELM: /* ƒXƒgƒŠƒbƒvƒwƒ‹ƒ€ */
- {
- struct status_change *tsc_data = battle_get_sc_data(bl);
-
- if(tsc_data && tsc_data[SC_CP_HELM].timer != -1 )
+ case RG_STRIPHELM:
+ equip = EQP_HELM;
+ cp_scid = SC_CP_HELM;
break;
- strip_per = 5+2*skilllv+strip_fix/5;
- strip_time = skill_get_time(skillid,skilllv)+strip_fix/2;
- if(rand()%100 < strip_per){
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,strip_time,0 );
- if(dstsd){
- for(i=0;i<MAX_INVENTORY;i++){
- if(dstsd->status.inventory[i].equip && dstsd->status.inventory[i].equip & 0x0100){
- pc_unequipitem(dstsd,i,0,BF_SKILL);
- break;
- }
- }
- }
- }
+ default:
+ map_freeblock_unlock();
+ return 1;
}
- break;
- // Full Strip [Celest]
- case ST_FULLSTRIP:
- {
- struct status_change *tsc_data = battle_get_sc_data(bl);
- int c=0, i, j;
- int striplist[2][4] = { { 0, 0, 0, 0 },
- { 0x0002, 0x0020, 0x0010, 0x0100 } };
+ if (tsc_data && (tsc_data[scid].timer != -1 || tsc_data[cp_scid].timer != -1))
+ break;
+ if (dstsd && dstsd->unstripable_equip & equip)
+ break;
- strip_per = 5+2*skilllv+strip_fix/5;
- strip_time = skill_get_time(skillid,skilllv)+strip_fix/2;
- for (i=0; i<4; i++) {
- if(tsc_data && tsc_data[SC_CP_WEAPON + i].timer != -1)
+ strip_fix = status_get_dex(src) - status_get_dex(bl);
+ if(strip_fix < 0)
+ strip_fix=0;
+ strip_per = 5+5*skilllv+strip_fix/5;
+ if (rand()%100 >= strip_per)
+ break;
+
+ if (dstsd) {
+ for (i=0;i<MAX_INVENTORY;i++) {
+ if (dstsd->status.inventory[i].equip && (dstsd->status.inventory[i].equip & equip)){
+ pc_unequipitem(dstsd,i,3);
break;
- if(rand()%100 < strip_per) {
- striplist[0][i] = 1;
- c++;
}
}
-
- if (c > 0) {
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- for (j=0; j<4 && c > 0; j++) {
- if (striplist[0][j]) {
- skill_status_change_start(bl,SC_STRIPWEAPON + i,skilllv,0,0,0,strip_time,0 );
- if(dstsd){
- for(i=0;i<MAX_INVENTORY;i++){
- if(dstsd->status.inventory[i].equip && dstsd->status.inventory[i].equip & striplist[1][j]){
- pc_unequipitem(dstsd,i,0,BF_SKILL);
- --c;
- break;
- }
- }
- }
+ if (i == MAX_INVENTORY)
+ break;
+ }
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ strip_time = skill_get_time(skillid,skilllv)+strip_fix/2;
+ status_change_start(bl,scid,skilllv,0,0,0,strip_time,0 );
+ break;
+ }
+ case ST_FULLSTRIP: // Celest
+ {
+ struct status_change *tsc_data;
+ int i, j, strip_time, strip_per, strip_fix;
+ int equip[4] = { EQP_WEAPON, EQP_SHIELD, EQP_ARMOR, EQP_HELM };
+ int scid[4] = { SC_STRIPWEAPON, SC_STRIPSHIELD, SC_STRIPARMOR, SC_STRIPHELM };
+ int cp_scid[4] = { SC_CP_WEAPON, SC_CP_SHIELD, SC_CP_ARMOR, SC_CP_HELM };
+
+ tsc_data = status_get_sc_data(bl);
+ strip_fix = status_get_dex(src) - status_get_dex(bl);
+ if(strip_fix < 0)
+ strip_fix = 0;
+ strip_per = 5+5*skilllv+strip_fix/5;
+ if (rand()%100 >= strip_per)
+ break;
+ strip_time = skill_get_time(skillid,skilllv)+strip_fix/2;
+
+ for (i=0; i<4; i++) {
+ if (dstsd) {
+ if (tsc_data && (tsc_data[scid[i]].timer != -1 || tsc_data[cp_scid[i]].timer != -1))
+ continue;
+ if (dstsd->unstripable_equip & equip[i])
+ continue;
+ for (j=0; j<MAX_INVENTORY; j++) {
+ if (dstsd->status.inventory[j].equip && (dstsd->status.inventory[j].equip & equip[i])){
+ pc_unequipitem(dstsd,j,3);
+ break;
}
}
+ if (j == MAX_INVENTORY)
+ continue;
}
+ status_change_start(bl,scid[i],skilllv,0,0,0,strip_time,0 );
}
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
break;
-
+ }
/* PotionPitcher */
case AM_POTIONPITCHER: /* ƒ|?ƒVƒ‡ƒ“ƒsƒbƒ`ƒƒ? */
@@ -3936,10 +3884,6 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
struct block_list tbl;
int i,x,hp = 0,sp = 0;
if(sd) {
- if(sd==dstsd) { // cancel use on oneself
- map_freeblock_unlock();
- return 1;
- }
x = skilllv%11 - 1;
i = pc_search_inventory(sd,skill_db[skillid].itemid[x]);
if(i < 0 || skill_db[skillid].itemid[x] <= 0) {
@@ -3959,7 +3903,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
pc_delitem(sd,i,skill_db[skillid].amount[x],0);
sd->state.potionpitcher_flag = 0;
if(sd->potion_per_hp > 0 || sd->potion_per_sp > 0) {
- hp = battle_get_max_hp(bl) * sd->potion_per_hp / 100;
+ hp = status_get_max_hp(bl) * sd->potion_per_hp / 100;
hp = hp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)/100;
if(dstsd) {
sp = dstsd->status.max_sp * sd->potion_per_sp / 100;
@@ -3969,13 +3913,13 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
else {
if(sd->potion_hp > 0) {
hp = sd->potion_hp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)/100;
- hp = hp * (100 + (battle_get_vit(bl)<<1)) / 100;
+ hp = hp * (100 + (status_get_vit(bl)<<1)) / 100;
if(dstsd)
hp = hp * (100 + pc_checkskill(dstsd,SM_RECOVERY)*10) / 100;
}
if(sd->potion_sp > 0) {
sp = sd->potion_sp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)/100;
- sp = sp * (100 + (battle_get_int(bl)<<1)) / 100;
+ sp = sp * (100 + (status_get_int(bl)<<1)) / 100;
if(dstsd)
sp = sp * (100 + pc_checkskill(dstsd,MG_SRECOVERY)*10) / 100;
}
@@ -3983,7 +3927,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
}
else {
hp = (1 + rand()%400) * (100 + skilllv*10) / 100;
- hp = hp * (100 + (battle_get_vit(bl)<<1)) / 100;
+ hp = hp * (100 + (status_get_vit(bl)<<1)) / 100;
if(dstsd)
hp = hp * (100 + pc_checkskill(dstsd,SM_RECOVERY)*10) / 100;
}
@@ -4000,39 +3944,16 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
}
break;
case AM_CP_WEAPON:
- {
- struct status_change *tsc_data = battle_get_sc_data(bl);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if(tsc_data && tsc_data[SC_STRIPWEAPON].timer != -1)
- skill_status_change_end(bl, SC_STRIPWEAPON, -1 );
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
- }
- break;
case AM_CP_SHIELD:
- {
- struct status_change *tsc_data = battle_get_sc_data(bl);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if(tsc_data && tsc_data[SC_STRIPSHIELD].timer != -1)
- skill_status_change_end(bl, SC_STRIPSHIELD, -1 );
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
- }
- break;
case AM_CP_ARMOR:
- {
- struct status_change *tsc_data = battle_get_sc_data(bl);
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if(tsc_data && tsc_data[SC_STRIPARMOR].timer != -1)
- skill_status_change_end(bl, SC_STRIPARMOR, -1 );
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
- }
- break;
case AM_CP_HELM:
{
- struct status_change *tsc_data = battle_get_sc_data(bl);
+ int scid = SC_STRIPWEAPON + (skillid - AM_CP_WEAPON);
+ struct status_change *tsc_data = status_get_sc_data(bl);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if(tsc_data && tsc_data[SC_STRIPHELM].timer != -1)
- skill_status_change_end(bl, SC_STRIPHELM, -1 );
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ if(tsc_data && tsc_data[scid].timer != -1)
+ status_change_end(bl, scid, -1 );
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
}
break;
@@ -4040,7 +3961,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
{
int i;
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage )
+ if(dstsd && dstsd->special_state.no_magic_damage )
break;
for(i=0;i<136;i++){
if(i==SC_RIDING || i== SC_FALCON || i==SC_HALLUCINATION || i==SC_WEIGHT50
@@ -4048,7 +3969,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
|| i==SC_STRIPHELM || i==SC_CP_WEAPON || i==SC_CP_SHIELD || i==SC_CP_ARMOR
|| i==SC_CP_HELM || i==SC_COMBO)
continue;
- skill_status_change_end(bl,i,-1);
+ status_change_end(bl,i,-1);
}
}
break;
@@ -4056,12 +3977,12 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
case TF_BACKSLIDING: /* ƒoƒbƒNƒXƒeƒbƒv */
battle_stopwalking(src,1);
skill_blown(src,bl,skill_get_blewcount(skillid,skilllv)|0x10000);
- if(src->type == BL_MOB)
- clif_fixmobpos((struct mob_data *)src);
- else if(src->type == BL_PET)
- clif_fixpetpos((struct pet_data *)src);
- else if(src->type == BL_PC)
+ if (sd)
clif_fixpos(src);
+ else if (md)
+ clif_fixmobpos(md);
+ else if (src->type == BL_PET)
+ clif_fixpetpos((struct pet_data *)src);
skill_addtimerskill(src,tick + 200,src->id,0,0,skillid,skilllv,0,flag);
break;
@@ -4077,7 +3998,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
break;
case SA_SPELLBREAKER: // ƒXƒyƒ‹ƒuƒŒƒCƒJ?
{
- struct status_change *sc_data = battle_get_sc_data(bl);
+ struct status_change *sc_data = status_get_sc_data(bl);
int sp;
if(sc_data && sc_data[SC_MAGICROD].timer != -1) {
if(dstsd) {
@@ -4140,9 +4061,9 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
}
break;
case SA_MAGICROD:
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage )
+ if (dstsd && dstsd->special_state.no_magic_damage )
break;
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
break;
case SA_AUTOSPELL: /* ƒI?ƒgƒXƒyƒ‹ */
clif_skill_nodamage(src,bl,skillid,skilllv,1);
@@ -4173,7 +4094,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
maxlv = 3;
}
if(spellid > 0)
- skill_status_change_start(src,SC_AUTOSPELL,skilllv,spellid,maxlv,0,
+ status_change_start(src,SC_AUTOSPELL,skilllv,spellid,maxlv,0,
skill_get_time(SA_AUTOSPELL,skilllv),0);
}
break;
@@ -4201,14 +4122,14 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
case NPC_PROVOCATION:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
if(md)
- clif_pet_performance(src,mob_db[md->class].skill[md->skillidx].val[0]);
+ clif_pet_performance(src,mob_db[md->class_].skill[md->skillidx].val[0]);
break;
case NPC_HALLUCINATION:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage )
+ if(dstsd && dstsd->special_state.no_magic_damage )
break;
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
break;
case NPC_KEEPING:
@@ -4216,25 +4137,25 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
{
int skill_time = skill_get_time(skillid,skilllv);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_time,0 );
- if (bl->type == BL_MOB)
- mob_changestate((struct mob_data *)src,MS_DELAY,skill_time);
- else if (bl->type == BL_PC)
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_time,0 );
+ if (md)
+ mob_changestate(md,MS_DELAY,skill_time);
+ else if (sd)
sd->attackabletime = sd->canmove_tick = tick + skill_time;
}
break;
case NPC_DARKBLESSING:
{
- int sc_def = 100 - battle_get_mdef(bl);
+ int sc_def = 100 - status_get_mdef(bl);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage )
+ if(dstsd && dstsd->special_state.no_magic_damage )
break;
- if(battle_get_elem_type(bl) == 7 || battle_get_race(bl) == 6)
+ if(status_get_elem_type(bl) == 7 || status_get_race(bl) == 6)
break;
if(rand()%100 < sc_def*(50+skilllv*5)/100) {
if(dstsd) {
- int hp = battle_get_hp(bl)-1;
+ int hp = status_get_hp(bl)-1;
pc_heal(dstsd,-hp,0);
}
else if(dstmd)
@@ -4245,16 +4166,17 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
case NPC_SELFDESTRUCTION: /* Ž©”š */
case NPC_SELFDESTRUCTION2: /* Ž©”š2 */
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,skillid,0,0,skill_get_time(skillid,skilllv),0);
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,skillid,0,0,skill_get_time(skillid,skilllv),0);
break;
case NPC_LICK:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_weapon_damage )
- break;
- if(dstsd)
+ if (dstsd) {
+ if (dstsd->special_state.no_weapon_damage )
+ break;
pc_heal(dstsd,0,-100);
+ }
if(rand()%100 < (skilllv*5)*sc_def_vit/100)
- skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case NPC_SUICIDE: /* Ž©Œˆ */
@@ -4269,26 +4191,106 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
case NPC_SUMMONSLAVE: /* Žè‰º¢Š« */
case NPC_SUMMONMONSTER: /* MOB¢Š« */
- if(md && !md->master_id){
- mob_summonslave(md,mob_db[md->class].skill[md->skillidx].val,skilllv,(skillid==NPC_SUMMONSLAVE)?1:0);
+ if(md)
+ mob_summonslave(md,mob_db[md->class_].skill[md->skillidx].val,skilllv,(skillid==NPC_SUMMONSLAVE)?1:0);
+ break;
+
+ case NPC_RECALL: //Žæ‚芪‚«ŒÄ‚Ñ–ß‚µ
+ if(md) {
+ int mobcount;
+ md->recallcount = 0;//‰Šú‰»
+ md->recall_flag = 0;
+ mobcount = mob_countslave(md);
+ if(mobcount > 0) {
+ md->recall_flag = 1; //mob.c‚Ì[Žæ‚芪‚«ƒ‚ƒ“ƒXƒ^[‚̈—]‚Å—˜—p
+ md->recallmob_count = mobcount;
+ }
+ }
+ break;
+
+ case NPC_RUNAWAY: //Œã‘Þ
+ if(md) {
+ int check;
+ int dist = skilllv;//Œã‘Þ‚·‚é‹——£
+ check = md->dir; //Ž©•ª‚ª‚ǂ̕ûŒü‚ÉŒü‚¢‚Ă邩ƒ`ƒFƒbƒN
+ md->attacked_id = 0;
+ md->target_id = 0;
+ md->state.targettype = NONE_ATTACKABLE;
+ md->state.skillstate = MSS_IDLE;
+ switch (check) {
+ case 0: //Ž©•ª‚ÌŒü‚¢‚Ä‚é•ûŒü‚Æ‹t‚Ɉړ®‚·‚é
+ mob_walktoxy(md,md->bl.x,md->bl.y-dist,0);//‚»‚µ‚ÄAˆÚ“®‚·‚é
+ break;
+ case 1:
+ mob_walktoxy(md,md->bl.x-dist,md->bl.y-dist,0);
+ break;
+ case 2:
+ mob_walktoxy(md,md->bl.x+dist,md->bl.y,0);
+ break;
+ case 3:
+ mob_walktoxy(md,md->bl.x+dist,md->bl.y+dist,0);
+ break;
+ case 4:
+ mob_walktoxy(md,md->bl.x,md->bl.y+dist,0);
+ break;
+ case 5:
+ mob_walktoxy(md,md->bl.x-dist,md->bl.y+dist,0);
+ break;
+ case 6:
+ mob_walktoxy(md,md->bl.x-dist,md->bl.y,0);
+ break;
+ case 7:
+ mob_walktoxy(md,md->bl.x-dist,md->bl.y-dist,0);
+ break;
+ }
}
break;
case NPC_TRANSFORMATION:
case NPC_METAMORPHOSIS:
if(md)
- mob_class_change(md,mob_db[md->class].skill[md->skillidx].val);
+ mob_class_change(md,mob_db[md->class_].skill[md->skillidx].val);
break;
case NPC_EMOTION: /* ƒGƒ‚?ƒVƒ‡ƒ“ */
if(md)
- clif_emotion(&md->bl,mob_db[md->class].skill[md->skillidx].val[0]);
+ clif_emotion(&md->bl,mob_db[md->class_].skill[md->skillidx].val[0]);
break;
case NPC_DEFENDER:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
break;
+ // Equipment breaking monster skills [Celest]
+ case NPC_BREAKWEAPON:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if(dstsd && battle_config.equipment_breaking)
+ pc_breakweapon(dstsd);
+ break;
+
+ case NPC_BREAKARMOR:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if(dstsd && battle_config.equipment_breaking)
+ pc_breakarmor(dstsd);
+ break;
+
+ case NPC_BREAKHELM:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if(dstsd && battle_config.equipment_breaking)
+ pc_breakhelm(dstsd);
+ break;
+
+ case NPC_BREAKSHIELD:
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ if(dstsd && battle_config.equipment_breaking)
+ pc_breakshield(dstsd);
+ break;
+
+ case NPC_EXPLOSIONSPIRITS: //NPC”š—ô”g“®
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ status_change_start(bl,SC_EXPLOSIONSPIRITS,skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ break;
+
case WE_MALE: /* ŒN‚¾‚¯‚ÍŒì‚邿 */
if(sd && dstsd){
int hp_rate=(skilllv <= 0)? 0:skill_db[skillid].hp_rate[skilllv-1];
@@ -4310,27 +4312,85 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
if(sd && dstsd){
if((dstsd = pc_get_partner(sd)) == NULL){
clif_skill_fail(sd,skillid,0,0);
+ map_freeblock_unlock();
return 0;
}
if(map[sd->bl.m].flag.nomemo || map[sd->bl.m].flag.nowarpto || map[dstsd->bl.m].flag.nowarp){
clif_skill_teleportmessage(sd,1);
+ map_freeblock_unlock();
return 0;
- }
+ }
skill_unitsetting(src,skillid,skilllv,sd->bl.x,sd->bl.y,0);
}
break;
+// parent-baby skills
+ case WE_BABY:
+ if(sd && dstsd){
+ struct map_session_data *f_sd = pc_get_father(sd);
+ struct map_session_data *m_sd = pc_get_mother(sd);
+ // if neither was found
+ if(!f_sd && !m_sd){
+ clif_skill_fail(sd,skillid,0,0);
+ map_freeblock_unlock();
+ return 0;
+ }
+ status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
+ if (f_sd) status_change_start(&f_sd->bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ if (m_sd) status_change_start(&m_sd->bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ }
+ break;
+
+ case WE_CALLPARENT:
+ if(sd && dstsd){
+ struct map_session_data *f_sd = pc_get_father(sd);
+ struct map_session_data *m_sd = pc_get_mother(sd);
+ // if neither was found
+ if(!f_sd && !m_sd){
+ clif_skill_fail(sd,skillid,0,0);
+ map_freeblock_unlock();
+ return 0;
+ }
+ if(map[sd->bl.m].flag.nomemo || map[sd->bl.m].flag.nowarpto || map[dstsd->bl.m].flag.nowarp){
+ clif_skill_teleportmessage(sd,1);
+ map_freeblock_unlock();
+ return 0;
+ }
+ if (f_sd) pc_setpos(f_sd,map[sd->bl.m].name,sd->bl.x,sd->bl.y,3);
+ if (m_sd) pc_setpos(f_sd,map[sd->bl.m].name,sd->bl.x,sd->bl.y,3);
+ }
+ break;
+
+ case WE_CALLBABY:
+ if(sd && dstsd){
+ if((dstsd = pc_get_child(sd)) == NULL){
+ clif_skill_fail(sd,skillid,0,0);
+ map_freeblock_unlock();
+ return 0;
+ }
+ if(map[sd->bl.m].flag.nomemo || map[sd->bl.m].flag.nowarpto || map[dstsd->bl.m].flag.nowarp){
+ clif_skill_teleportmessage(sd,1);
+ map_freeblock_unlock();
+ return 0;
+ }
+ pc_setpos(dstsd,map[sd->bl.m].name,sd->bl.x,sd->bl.y,3);
+ }
+ break;
+
case PF_HPCONVERSION: /* ƒ‰ƒCƒt’u‚«Š·‚¦ */
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if(sd){
- int conv_hp=0,conv_sp=0;
- conv_hp=sd->status.hp/10; //Šî–{‚ÍHP‚Ì10%
- sd->status.hp -= conv_hp; //HP‚ðŒ¸‚ç‚·
- conv_sp=conv_hp*10*skilllv/100;
- conv_sp=(sd->status.sp+conv_sp>sd->status.max_sp)?sd->status.max_sp-sd->status.sp:conv_sp;
- sd->status.sp += conv_sp; //SP‚ð?‚â‚·
- pc_heal(sd,-conv_hp,conv_sp);
- clif_heal(sd->fd,SP_SP,conv_sp);
+ clif_skill_nodamage(src, bl, skillid, skilllv, 1);
+ if (sd) {
+ int hp, sp;
+ hp = sd->status.max_hp / 10; //Šî–{‚ÍHP‚Ì10%
+ sp = hp * 10 * skilllv / 100;
+ if (sd->status.sp + sp > sd->status.max_sp)
+ sp = sd->status.max_sp - sd->status.sp;
+ // we need to check with the sp that was taken away when casting too
+ if (sd->status.sp + skill_get_sp(skillid, skilllv) >= sd->status.max_sp)
+ hp = sp = 0;
+ pc_heal(sd, -hp, sp);
+ clif_heal(sd->fd, SP_SP, sp);
+ clif_updatestatus(sd, SP_SP);
}
break;
case HT_REMOVETRAP: /* ƒŠƒ€?ƒuƒgƒ‰ƒbƒv */
@@ -4346,13 +4406,13 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
(su->group->unit_id != 0x92)){ //?‚ðŽæ‚è•Ô‚·
if(sd){
if(battle_config.skill_removetrap_type == 1){
- for(i=0;i<10;i++) {
- if(skill_db[su->group->skill_id].itemid[i] > 0){
- memset(&item_tmp,0,sizeof(item_tmp));
- item_tmp.nameid = skill_db[su->group->skill_id].itemid[i];
- item_tmp.identify = 1;
- if(item_tmp.nameid && (flag=pc_additem(sd,&item_tmp,skill_db[su->group->skill_id].amount[i]))){
- clif_additem(sd,0,0,flag);
+ for(i=0;i<10;i++) {
+ if(skill_db[su->group->skill_id].itemid[i] > 0){
+ memset(&item_tmp,0,sizeof(item_tmp));
+ item_tmp.nameid = skill_db[su->group->skill_id].itemid[i];
+ item_tmp.identify = 1;
+ if(item_tmp.nameid && (flag=pc_additem(sd,&item_tmp,skill_db[su->group->skill_id].amount[i]))){
+ clif_additem(sd,0,0,flag);
map_addflooritem(&item_tmp,skill_db[su->group->skill_id].amount[i],sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0);
}
}
@@ -4366,12 +4426,12 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0);
}
}
-
+
}
if(su->group->unit_id == 0x91 && su->group->val2){
struct block_list *target=map_id2bl(su->group->val2);
if(target && (target->type == BL_PC || target->type == BL_MOB))
- skill_status_change_end(target,SC_ANKLE,-1);
+ status_change_end(target,SC_ANKLE,-1);
}
skill_delunit(su);
}
@@ -4383,6 +4443,12 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
struct skill_unit *su=NULL;
if((bl->type==BL_SKILL) && (su=(struct skill_unit *)bl) && (su->group) ){
switch(su->group->unit_id){
+ case 0x91: // ankle snare
+ if (su->group->val2 != 0)
+ // if it is already trapping something don't spring it,
+ // remove trap should be used instead
+ break;
+ // otherwise fallthrough to below
case 0x8f: /* ƒuƒ‰ƒXƒgƒ}ƒCƒ“ */
case 0x90: /* ƒXƒLƒbƒhƒgƒ‰ƒbƒv */
case 0x93: /* ƒ‰ƒ“ƒhƒ}ƒCƒ“ */
@@ -4407,25 +4473,27 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
break;
case AS_SPLASHER: /* ƒxƒiƒ€ƒXƒvƒ‰ƒbƒVƒƒ? */
- if((double)battle_get_max_hp(bl)*2/3 < battle_get_hp(bl)) //HP‚ª2/3ˆÈã?‚Á‚Ä‚¢‚½‚玸”s
+ if((double)status_get_max_hp(bl)*2/3 < status_get_hp(bl)) { //HP‚ª2/3ˆÈã?‚Á‚Ä‚¢‚½‚玸”s
+ map_freeblock_unlock();
return 1;
+ }
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,skillid,src->id,0,skill_get_time(skillid,skilllv),0 );
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,skillid,src->id,skill_get_time(skillid,skilllv),1000,0 );
break;
case PF_MINDBREAKER: /* ƒvƒƒ{ƒbƒN */
{
- struct status_change *sc_data = battle_get_sc_data(bl);
+ struct status_change *sc_data = status_get_sc_data(bl);
/* MVPmob‚Æ•sŽ€‚É‚Í?‚©‚È‚¢ */
- if((bl->type==BL_MOB && battle_get_mode(bl)&0x20) || battle_check_undead(battle_get_race(bl),battle_get_elem_type(bl))) //•sŽ€‚É‚Í?‚©‚È‚¢
+ if((dstmd && status_get_mode(bl)&0x20) || battle_check_undead(status_get_race(bl),status_get_elem_type(bl))) //•sŽ€‚É‚Í?‚©‚È‚¢
{
map_freeblock_unlock();
return 1;
}
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
+ status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
if(dstmd && dstmd->skilltimer!=-1 && dstmd->state.skillcastcancel) // ‰r¥–WŠQ
skill_castcancel(bl,0);
@@ -4435,22 +4503,55 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
if(sc_data){
if(sc_data[SC_FREEZE].timer!=-1)
- skill_status_change_end(bl,SC_FREEZE,-1);
+ status_change_end(bl,SC_FREEZE,-1);
if(sc_data[SC_STONE].timer!=-1 && sc_data[SC_STONE].val2==0)
- skill_status_change_end(bl,SC_STONE,-1);
+ status_change_end(bl,SC_STONE,-1);
if(sc_data[SC_SLEEP].timer!=-1)
- skill_status_change_end(bl,SC_SLEEP,-1);
+ status_change_end(bl,SC_SLEEP,-1);
}
- if(bl->type==BL_MOB) {
- int range = skill_get_range(skillid,skilllv);
- if(range < 0)
- range = battle_get_range(src) - (range + 1);
- mob_target((struct mob_data *)bl,src,range);
+ if(dstmd)
+ mob_target(dstmd,src,skill_get_range(skillid,skilllv));
+ }
+ break;
+
+ case PF_SOULCHANGE:
+ {
+ int sp1 = 0, sp2 = 0;
+ if (sd) {
+ if (dstsd) {
+ sp1 = sd->status.sp > dstsd->status.max_sp ? dstsd->status.max_sp : sd->status.sp;
+ sp2 = dstsd->status.sp > sd->status.max_sp ? sd->status.max_sp : dstsd->status.sp;
+ sd->status.sp = sp2;
+ dstsd->status.sp = sp1;
+ clif_heal(sd->fd,SP_SP,sp2);
+ clif_updatestatus(sd,SP_SP);
+ clif_heal(dstsd->fd,SP_SP,sp1);
+ clif_updatestatus(dstsd,SP_SP);
+ } else if (dstmd) {
+ if (dstmd->state.soul_change_flag) {
+ clif_skill_fail(sd,skillid,0,0);
+ map_freeblock_unlock();
+ return 0;
+ }
+ sp2 = sd->status.max_sp * 3 /100;
+ if (sd->status.sp + sp2 > sd->status.max_sp)
+ sp2 = sd->status.max_sp - sd->status.sp;
+ sd->status.sp += sp2;
+ clif_heal(sd->fd,SP_SP,sp2);
+ clif_updatestatus(sd,SP_SP);
+ dstmd->state.soul_change_flag = 1;
+ }
}
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
}
break;
+ case PF_SPIDERWEB: /* ƒXƒpƒCƒ_?ƒEƒFƒbƒu */
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ skill_unitsetting(src,skillid,skilllv,bl->x,bl->y,0);
+ break;
+
// Weapon Refining [Celest]
case WS_WEAPONREFINE:
if(sd)
@@ -4461,12 +4562,18 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
case CR_SLIMPITCHER:
{
if (sd && flag&1) {
- int hp = sd->potion_hp * (100 + pc_checkskill(sd,CR_SLIMPITCHER)*5 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)/100;
- hp = hp * (100 + (battle_get_vit(bl)<<1))/100;
- if (dstsd)
+ struct block_list tbl;
+ int hp = sd->potion_hp * (100 + pc_checkskill(sd,CR_SLIMPITCHER)*10 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)/100;
+ hp = hp * (100 + (status_get_vit(bl)<<1))/100;
+ if (dstsd) {
hp = hp * (100 + pc_checkskill(dstsd,SM_RECOVERY)*10)/100;
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- battle_heal(src,bl,hp,0,0);
+ }
+ tbl.id = 0;
+ tbl.m = src->m;
+ tbl.x = src->x;
+ tbl.y = src->y;
+ clif_skill_nodamage(&tbl,bl,AL_HEAL,hp,1);
+ battle_heal(NULL,bl,hp,0,0);
}
}
break;
@@ -4474,13 +4581,13 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
case CR_FULLPROTECTION:
{
int i, skilltime;
- struct status_change *tsc_data = battle_get_sc_data(bl);
+ struct status_change *tsc_data = status_get_sc_data(bl);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
skilltime = skill_get_time(skillid,skilllv);
for (i=0; i<4; i++) {
if(tsc_data && tsc_data[SC_STRIPWEAPON + i].timer != -1)
- skill_status_change_end(bl, SC_STRIPWEAPON + i, -1 );
- skill_status_change_start(bl,SC_CP_WEAPON + i,skilllv,0,0,0,skilltime,0 );
+ status_change_end(bl, SC_STRIPWEAPON + i, -1 );
+ status_change_start(bl,SC_CP_WEAPON + i,skilllv,0,0,0,skilltime,0 );
}
}
break;
@@ -4498,6 +4605,15 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
}
}
break;
+ case ST_PRESERVE:
+ if (sd){
+ if (sd->sc_count && sd->sc_data[SC_PRESERVE].timer != -1)
+ status_change_end(src, SC_PRESERVE, -1 );
+ else
+ status_change_start(src,SC_PRESERVE,skilllv,0,0,0,skill_get_time(skillid, skilllv),0 );
+ clif_skill_nodamage(src,src,skillid,skilllv,1);
+ }
+ break;
// New guild skills [Celest]
case GD_BATTLEORDER:
@@ -4511,7 +4627,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
}
if(flag&1) {
if (dstsd && dstsd->status.guild_id == sd->status.guild_id) {
- skill_status_change_start(&dstsd->bl,SC_BATTLEORDERS,skilllv,0,0,0,0,0 );
+ status_change_start(&dstsd->bl,SC_BATTLEORDERS,skilllv,0,0,0,0,0 );
}
}
else if (sd && sd->status.guild_id > 0 && (g = guild_search(sd->status.guild_id)) &&
@@ -4521,6 +4637,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
src->m,src->x-15,src->y-15,src->x+15,src->y+15,0,
src,skillid,skilllv,tick, flag|BCT_ALL|1,
skill_castend_nodamage_id);
+ pc_blockskill_start (sd, skillid, 300000);
}
}
break;
@@ -4535,7 +4652,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
}
if(flag&1) {
if (dstsd && dstsd->status.guild_id == sd->status.guild_id) {
- skill_status_change_start(&dstsd->bl,SC_REGENERATION,skilllv,0,0,0,0,0 );
+ status_change_start(&dstsd->bl,SC_REGENERATION,skilllv,0,0,0,0,0 );
}
}
else if (sd && sd->status.guild_id > 0 && (g = guild_search(sd->status.guild_id)) &&
@@ -4545,10 +4662,11 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
src->m,src->x-15,src->y-15,src->x+15,src->y+15,0,
src,skillid,skilllv,tick, flag|BCT_ALL|1,
skill_castend_nodamage_id);
+ pc_blockskill_start (sd, skillid, 300000);
}
}
break;
- case GD_RESTORE:
+ case GD_RESTORE:
{
struct guild *g = NULL;
// Only usable during WoE
@@ -4560,8 +4678,8 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
if(flag&1) {
if (dstsd && dstsd->status.guild_id == sd->status.guild_id) {
int hp, sp;
- hp = dstsd->status.max_hp*0.9;
- sp = dstsd->status.max_sp*0.9;
+ hp = dstsd->status.max_hp*9/10;
+ sp = dstsd->status.max_sp*9/10;
sp = dstsd->status.sp + sp <= dstsd->status.max_sp ? sp : dstsd->status.max_sp - dstsd->status.sp;
clif_skill_nodamage(src,bl,AL_HEAL,hp,1);
battle_heal(NULL,bl,hp,sp,0);
@@ -4574,6 +4692,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
src->m,src->x-15,src->y-15,src->x+15,src->y+15,0,
src,skillid,skilllv,tick, flag|BCT_ALL|1,
skill_castend_nodamage_id);
+ pc_blockskill_start (sd, skillid, 300000);
}
}
break;
@@ -4581,10 +4700,12 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
{
int dx[9]={-1, 1, 0, 0,-1, 1,-1, 1, 0};
int dy[9]={ 0, 0, 1,-1, 1,-1,-1, 1, 0};
- int c, j = 0;
+ int j = 0;
struct guild *g = NULL;
// Only usable during WoE
- if (!agit_flag) {
+ if (!agit_flag ||
+ (sd && map[sd->bl.m].flag.nowarpto && // if not allowed to warp to the map
+ guild_mapname2gc(sd->mapname) == NULL)) { // and it's not a castle...
clif_skill_fail(sd,skillid,0,0);
map_freeblock_unlock();
return 0;
@@ -4594,17 +4715,21 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
strcmp(sd->status.name,g->master)==0) {
for(i = 0; i < g->max_member; i++, j++) {
if (j>8) j=0;
- if ((dstsd = g->member[i].sd) != NULL && sd != dstsd &&
- !map[sd->bl.m].flag.nowarpto && !map[dstsd->bl.m].flag.nowarp) {
+ if ((dstsd = g->member[i].sd) != NULL && sd != dstsd) {
+ if (map[dstsd->bl.m].flag.nowarp &&
+ guild_mapname2gc(sd->mapname) == NULL)
+ continue;
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- if ((c=read_gat(sd->bl.m,sd->bl.x+dx[j],sd->bl.y+dy[j]))==1 || c==5)
+ if(map_getcell(sd->bl.m,sd->bl.x+dx[j],sd->bl.y+dy[j],CELL_CHKNOPASS))
dx[j] = dy[j] = 0;
pc_setpos(dstsd, sd->mapname, sd->bl.x+dx[j], sd->bl.y+dy[j], 2);
}
}
+ pc_blockskill_start (sd, skillid, 300000);
}
}
break;
+
default:
printf("Unknown skill used:%d\n",skillid);
map_freeblock_unlock();
@@ -4653,7 +4778,7 @@ int skill_castend_id( int tid, unsigned int tick, int id,int data )
}
if(sd->skillid == PR_LEXAETERNA) {
- struct status_change *sc_data = battle_get_sc_data(bl);
+ struct status_change *sc_data = status_get_sc_data(bl);
if(sc_data && (sc_data[SC_FREEZE].timer != -1 || (sc_data[SC_STONE].timer != -1 && sc_data[SC_STONE].val2 == 0))) {
clif_skill_fail(sd,sd->skillid,0,0);
sd->canact_tick = tick;
@@ -4663,7 +4788,7 @@ int skill_castend_id( int tid, unsigned int tick, int id,int data )
}
}
else if(sd->skillid == RG_BACKSTAP) {
- int dir = map_calc_dir(&sd->bl,bl->x,bl->y),t_dir = battle_get_dir(bl);
+ int dir = map_calc_dir(&sd->bl,bl->x,bl->y),t_dir = status_get_dir(bl);
int dist = distance(sd->bl.x,sd->bl.y,bl->x,bl->y);
if(bl->type != BL_SKILL && (dist == 0 || map_check_dir(dir,t_dir))) {
clif_skill_fail(sd,sd->skillid,0,0);
@@ -4686,7 +4811,7 @@ int skill_castend_id( int tid, unsigned int tick, int id,int data )
int fail_flag = 1;
if(inf2 & 0x400 && battle_check_target(&sd->bl,bl, BCT_PARTY) > 0)
fail_flag = 0;
- if(inf2 & 0x800 && sd->status.guild_id > 0 && sd->status.guild_id == battle_get_guild_id(bl))
+ if(inf2 & 0x800 && sd->status.guild_id > 0 && sd->status.guild_id == status_get_guild_id(bl))
fail_flag = 0;
if(fail_flag) {
clif_skill_fail(sd,sd->skillid,0,0);
@@ -4699,7 +4824,7 @@ int skill_castend_id( int tid, unsigned int tick, int id,int data )
range = skill_get_range(sd->skillid,sd->skilllv);
if(range < 0)
- range = battle_get_range(&sd->bl) - (range + 1);
+ range = status_get_range(&sd->bl) - (range + 1);
range += battle_config.pc_skill_add_range;
if((sd->skillid == MO_EXTREMITYFIST && sd->sc_data[SC_COMBO].timer != -1 && sd->sc_data[SC_COMBO].val1 == MO_COMBOFINISH) ||
(sd->skillid == CH_TIGERFIST && sd->sc_data[SC_COMBO].timer != -1 && sd->sc_data[SC_COMBO].val1 == MO_COMBOFINISH) ||
@@ -4742,7 +4867,7 @@ int skill_castend_id( int tid, unsigned int tick, int id,int data )
skill_castend_damage_id(&sd->bl,bl,sd->skillid,sd->skilllv,tick,0);
break;
case 1:/* Žx‰‡Œn */
- if( (sd->skillid==AL_HEAL || (sd->skillid==ALL_RESURRECTION && bl->type != BL_PC) || sd->skillid==PR_ASPERSIO) && battle_check_undead(battle_get_race(bl),battle_get_elem_type(bl)))
+ if( (sd->skillid==AL_HEAL || (sd->skillid==ALL_RESURRECTION && bl->type != BL_PC) || sd->skillid==PR_ASPERSIO) && battle_check_undead(status_get_race(bl),status_get_elem_type(bl)))
skill_castend_damage_id(&sd->bl,bl,sd->skillid,sd->skilllv,tick,0);
else
skill_castend_nodamage_id(&sd->bl,bl,sd->skillid,sd->skilllv,tick,0);
@@ -4761,21 +4886,21 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil
struct map_session_data *sd=NULL;
int i,tmpx = 0,tmpy = 0, x1 = 0, y1 = 0;
- if(skilllv <= 0) return 0;
+ //if(skilllv <= 0) return 0;
+ if(skillid > 0 && skilllv <= 0) return 0; // celest
nullpo_retr(0, src);
if(src->type==BL_PC){
nullpo_retr(0, sd=(struct map_session_data *)src);
}
- if( skillid != WZ_METEOR &&
- skillid != WZ_SIGHTRASHER &&
+ if( skillid != WZ_METEOR &&
skillid != AM_CANNIBALIZE &&
skillid != AM_SPHEREMINE)
clif_skill_poseffect(src,skillid,skilllv,x,y,tick);
- if (skillnotok(skillid, sd)) // [MouseJstr]
- return 0;
+ if (sd && skillnotok(skillid, sd)) // [MouseJstr]
+ return 0;
switch(skillid)
{
@@ -4792,20 +4917,31 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil
break;
case BS_HAMMERFALL: /* ƒnƒ“ƒ}?ƒtƒH?ƒ‹ */
- skill_area_temp[1]=src->id;
- skill_area_temp[2]=x;
- skill_area_temp[3]=y;
- map_foreachinarea(skill_area_sub,
- src->m,x-2,y-2,x+2,y+2,0,
- src,skillid,skilllv,tick, flag|BCT_ENEMY|2,
- skill_castend_nodamage_id);
+ {
+ int r = 2;
+ if (skilllv > 5) {
+ r = 14;
+ skilllv = 5; // ƒXƒ^ƒ“—¦ã‚ª‚è‚·‚¬‚邽‚ߌvŽZ‚ÍLv5‚ŌŒè
+ }
+ skill_area_temp[1] = src->id;
+ skill_area_temp[2] = x;
+ skill_area_temp[3] = y;
+ map_foreachinarea (skill_area_sub,
+ src->m, x-r, y-r, x+r, y+r, 0,
+ src, skillid, skilllv, tick, flag|BCT_ENEMY|2,
+ skill_castend_nodamage_id);
+ }
break;
case HT_DETECTING: /* ƒfƒBƒeƒNƒeƒBƒ“ƒO */
{
- const int range=7;
- map_foreachinarea( skill_status_change_timer_sub,
- src->m, src->x-range, src->y-range, src->x+range,src->y+range,0,
+ int range=skilllv*2+1;
+ if(src->x!=x)
+ x+=(src->x-x>0)?-range:range;
+ if(src->y!=y)
+ y+=(src->y-y>0)?-range:range;
+ map_foreachinarea( status_change_timer_sub,
+ src->m, x-range, y-range, x+range,y+range,0,
src,SC_SIGHT,tick);
}
break;
@@ -4816,15 +4952,15 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil
case AL_PNEUMA: /* ƒjƒ…?ƒ} */
case WZ_ICEWALL: /* ƒAƒCƒXƒEƒH?ƒ‹ */
case WZ_FIREPILLAR: /* ƒtƒ@ƒCƒAƒsƒ‰? */
- case WZ_SIGHTRASHER:
case WZ_QUAGMIRE: /* ƒNƒ@ƒOƒ}ƒCƒA */
case WZ_VERMILION: /* ƒ?ƒhƒIƒuƒ”ƒ@?ƒ~ƒŠƒIƒ“ */
- case WZ_FROSTNOVA: /* ƒtƒƒXƒgƒmƒ”ƒ@ */
+ //case WZ_FROSTNOVA: /* ƒtƒƒXƒgƒmƒ”ƒ@ */
case WZ_STORMGUST: /* ƒXƒg?ƒ€ƒKƒXƒg */
case WZ_HEAVENDRIVE: /* ƒwƒ”ƒ“ƒYƒhƒ‰ƒCƒu */
case PR_SANCTUARY: /* ƒTƒ“ƒNƒ`ƒ…ƒAƒŠ */
case PR_MAGNUS: /* ƒ}ƒOƒkƒXƒGƒNƒ\ƒVƒYƒ€ */
case CR_GRANDCROSS: /* ƒOƒ‰ƒ“ƒhƒNƒƒX */
+ case NPC_DARKGRANDCROSS: /*ˆÅƒOƒ‰ƒ“ƒhƒNƒƒX*/
case HT_SKIDTRAP: /* ƒXƒLƒbƒhƒgƒ‰ƒbƒv */
case HT_LANDMINE: /* ƒ‰ƒ“ƒhƒ}ƒCƒ“ */
case HT_ANKLESNARE: /* ƒAƒ“ƒNƒ‹ƒXƒlƒA */
@@ -4836,12 +4972,11 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil
case HT_CLAYMORETRAP: /* ƒNƒŒƒCƒ‚ƒA?ƒgƒ‰ƒbƒv */
case AS_VENOMDUST: /* ƒxƒmƒ€ƒ_ƒXƒg */
case AM_DEMONSTRATION: /* ƒfƒ‚ƒ“ƒXƒgƒŒ?ƒVƒ‡ƒ“ */
- case PF_SPIDERWEB: /* ƒXƒpƒCƒ_?ƒEƒFƒbƒu */
case PF_FOGWALL: /* ƒtƒHƒOƒEƒH?ƒ‹ */
case HT_TALKIEBOX: /* ƒg?ƒL?ƒ{ƒbƒNƒX */
skill_unitsetting(src,skillid,skilllv,x,y,0);
break;
-
+
case RG_GRAFFITI: /* Graffiti [Valaris] */
skill_clear_unitgroup(src);
skill_unitsetting(src,skillid,skilllv,x,y,0);
@@ -4859,7 +4994,7 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil
{
int flag=0;
for(i=0;i<2+(skilllv>>1);i++) {
- int j=0, c;
+ int j=0;
do {
tmpx = x + (rand()%7 - 3);
tmpy = y + (rand()%7 - 3);
@@ -4872,7 +5007,7 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil
else if(tmpy >= map[src->m].ys)
tmpy = map[src->m].ys - 1;
j++;
- } while(((c=map_getcell(src->m,tmpx,tmpy))==1 || c==5) && j<100);
+ } while((map_getcell(src->m,tmpx,tmpy,CELL_CHKNOPASS)) && j<100);
if(j >= 100)
continue;
if(flag==0){
@@ -4903,37 +5038,43 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil
pc_movepos(sd,x,y);
}else if( src->type==BL_MOB )
mob_warp((struct mob_data *)src,-1,x,y,0);
+ if (sd)
+ pc_blockskill_start (sd, MO_EXTREMITYFIST, 2000);
break;
case AM_CANNIBALIZE: // ƒoƒCƒIƒvƒ‰ƒ“ƒg
- if(sd){
- int mx,my,id=0;
+ if(sd) {
+ int id;
+ int summons[5] = { 1020, 1068, 1118, 1500, 1368 };
struct mob_data *md;
- mx = x;// + (rand()%10 - 5);
- my = y;// + (rand()%10 - 5);
- id=mob_once_spawn(sd,"this",mx,my,"--ja--",1118,1,"");
+ // Correct info, don't change any of this! [celest]
+ id = mob_once_spawn (sd, "this", x, y, "--ja--", summons[skilllv-1] ,1,"");
+
if( (md=(struct mob_data *)map_id2bl(id)) !=NULL ){
- md->master_id=sd->bl.id;
- md->hp=2210+skilllv*200;
- md->state.special_mob_ai=1;
- md->deletetimer=add_timer(gettick()+skill_get_time(skillid,skilllv),mob_timer_delete,id,0);
- }
+ md->master_id = sd->bl.id;
+ // different levels of HP according to skill level
+ md->hp = 1500 + skilllv * 200 + sd->status.base_level * 10;
+ md->state.special_mob_ai = 1;
+ //”ñˆÚ“®‚ŃAƒNƒeƒBƒu‚Å”½Œ‚‚·‚é[0x0:”ñˆÚ“® 0x1:ˆÚ“® 0x4:ACT 0x8:”ñACT 0x40:”½Œ‚–³ 0x80:”½Œ‚—L]
+ md->mode = 0x0 + 0x4 + 0x80;
+ md->deletetimer = add_timer (gettick() + skill_get_time(skillid,skilllv), mob_timer_delete, id, 0);
+ }
+ // To-do: ¢ŠÒ‚³‚ê‚郂ƒ“ƒXƒ^[‚ɂ͢ŠÒ‚µ‚½ƒvƒŒ[ƒ„[‚Ì–¼‘O‚ª•t‚«‚Ü‚·
+ // (attach name of player?)
clif_skill_poseffect(src,skillid,skilllv,x,y,tick);
}
break;
case AM_SPHEREMINE: // ƒXƒtƒBƒA?ƒ}ƒCƒ“
if(sd){
- int mx,my,id=0;
+ int id;
struct mob_data *md;
- mx = x;// + (rand()%10 - 5);
- my = y;// + (rand()%10 - 5);
- id=mob_once_spawn(sd,"this",mx,my,"--ja--",1142,1,"");
+ id = mob_once_spawn(sd, "this", x, y, "--ja--", 1142, 1, "");
if( (md=(struct mob_data *)map_id2bl(id)) !=NULL ){
- md->master_id=sd->bl.id;
- md->hp=1000+skilllv*200;
- md->state.special_mob_ai=2;
- md->deletetimer=add_timer(gettick()+skill_get_time(skillid,skilllv),mob_timer_delete,id,0);
+ md->master_id = sd->bl.id;
+ md->hp = 2000 + skilllv * 400;
+ md->state.special_mob_ai = 2;
+ md->deletetimer = add_timer (gettick() + skill_get_time(skillid,skilllv), mob_timer_delete, id, 0);
}
clif_skill_poseffect(src,skillid,skilllv,x,y,tick);
}
@@ -4943,24 +5084,24 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil
case CR_SLIMPITCHER:
{
if (sd) {
- int x = skilllv%11 - 1;
- int i = pc_search_inventory(sd,skill_db[skillid].itemid[x]);
- if(i < 0 || skill_db[skillid].itemid[x] <= 0 || sd->inventory_data[i] == NULL ||
- sd->status.inventory[i].amount < skill_db[skillid].amount[x]) {
+ int i = skilllv%11 - 1;
+ int j = pc_search_inventory(sd,skill_db[skillid].itemid[i]);
+ if(j < 0 || skill_db[skillid].itemid[i] <= 0 || sd->inventory_data[j] == NULL ||
+ sd->status.inventory[j].amount < skill_db[skillid].amount[i]) {
clif_skill_fail(sd,skillid,0,0);
- map_freeblock_unlock();
return 1;
}
sd->state.potionpitcher_flag = 1;
sd->potion_hp = 0;
- run_script(sd->inventory_data[i]->use_script,0,sd->bl.id,0);
- pc_delitem(sd,i,skill_db[skillid].amount[x],0);
+ run_script(sd->inventory_data[j]->use_script,0,sd->bl.id,0);
+ pc_delitem(sd,j,skill_db[skillid].amount[i],0);
sd->state.potionpitcher_flag = 0;
+ clif_skill_poseffect(src,skillid,skilllv,x,y,tick);
if(sd->potion_hp > 0) {
map_foreachinarea(skill_area_sub,
src->m,x-3,y-3,x+3,y+3,0,
- src,skillid,skilllv,tick,flag|BCT_ALL|1,
- skill_castend_nodamage_id);
+ src,skillid,skilllv,tick,flag|BCT_PARTY|1,
+ skill_castend_nodamage_id);
}
}
}
@@ -4982,13 +5123,13 @@ int skill_castend_map( struct map_session_data *sd,int skill_num, const char *ma
if( sd->bl.prev == NULL || pc_isdead(sd) )
return 0;
- if(skillnotok(skill_num, sd))
- return 0;
+ if(skillnotok(skill_num, sd))
+ return 0;
if( sd->opt1>0 || sd->status.option&2 )
return 0;
//ƒXƒLƒ‹‚ªŽg‚¦‚È‚¢?‘ÔˆÙí’†
- if(sd->sc_data){
+ if(sd->sc_count){
if( sd->sc_data[SC_DIVINA].timer!=-1 ||
sd->sc_data[SC_ROKISWEIL].timer!=-1 ||
sd->sc_data[SC_AUTOCOUNTER].timer != -1 ||
@@ -4997,10 +5138,6 @@ int skill_castend_map( struct map_session_data *sd,int skill_num, const char *ma
sd->sc_data[SC_BERSERK].timer != -1 ||
sd->sc_data[SC_MARIONETTE].timer != -1)
return 0;
-
- if (sd->sc_data[SC_BLOCKSKILL].timer!=-1)
- if (skill_num == sd->sc_data[SC_BLOCKSKILL].val3)
- return 0;
}
if( skill_num != sd->skillid) /* •s³ƒpƒPƒbƒg‚炵‚¢ */
@@ -5026,13 +5163,14 @@ int skill_castend_map( struct map_session_data *sd,int skill_num, const char *ma
case AL_WARP: /* ƒ?ƒvƒ|?ƒ^ƒ‹ */
{
- const struct point *p[]={
- &sd->status.save_point,&sd->status.memo_point[0],
- &sd->status.memo_point[1],&sd->status.memo_point[2],
- };
+ const struct point *p[4];
struct skill_unit_group *group;
int i;
int maxcount=0;
+ p[0] = &sd->status.save_point;
+ p[1] = &sd->status.memo_point[0];
+ p[2] = &sd->status.memo_point[1];
+ p[3] = &sd->status.memo_point[2];
if((maxcount = skill_get_maxcount(sd->skillid)) > 0) {
int c;
@@ -5064,7 +5202,7 @@ int skill_castend_map( struct map_session_data *sd,int skill_num, const char *ma
return 0;
if((group=skill_unitsetting(&sd->bl,sd->skillid,sd->skilllv,sd->skillx,sd->skilly,0))==NULL)
return 0;
- group->valstr=(char *)aCalloc(24,sizeof(char));
+ group->valstr=(char *)aCallocA(24,sizeof(char));
memcpy(group->valstr,map,24);
group->val2=(x<<16)|y;
}
@@ -5081,561 +5219,176 @@ int skill_castend_map( struct map_session_data *sd,int skill_num, const char *ma
struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid,int skilllv,int x,int y,int flag)
{
struct skill_unit_group *group;
- int i,count=1,limit=10000,val1=0,val2=0;
- int target=BCT_ENEMY,interval=1000,range=0;
- int dir=0,aoe_diameter=0; // -- aoe_diameter (moonsoul) added for sage Area Of Effect skills
- struct status_change *sc_data = battle_get_sc_data(src); // for firewall and fogwall - celest
+ int i,limit,val1=0,val2=0,val3=0;
+ int count=0;
+ int target,interval,range,unit_flag;
+ struct skill_unit_layout *layout;
+ struct status_change *sc_data;
+ int active_flag=1;
nullpo_retr(0, src);
+ limit = skill_get_time(skillid,skilllv);
+ range = skill_get_unit_range(skillid);
+ interval = skill_get_unit_interval(skillid);
+ target = skill_get_unit_target(skillid);
+ unit_flag = skill_get_unit_flag(skillid);
+ layout = skill_get_unit_layout(skillid,skilllv,src,x,y);
+
+ if (unit_flag&UF_DEFNOTENEMY && battle_config.defnotenemy)
+ target = BCT_NOENEMY;
+
+ sc_data = status_get_sc_data(src); // for firewall and fogwall - celest
+
switch(skillid){ /* Ý’è */
case MG_SAFETYWALL: /* ƒZƒCƒtƒeƒBƒEƒH?ƒ‹ */
- limit=skill_get_time(skillid,skilllv);
val2=skilllv+1;
- interval = -1;
- target=(battle_config.defnotenemy)?BCT_NOENEMY:BCT_ALL;
break;
-
case MG_FIREWALL: /* ƒtƒ@ƒCƒ„?ƒEƒH?ƒ‹ */
- if(src->x == x && src->y == y)
- dir = 2;
- else
- dir=map_calc_dir(src,x,y);
- if(dir&1) count=5;
- else count=3;
- limit=skill_get_time(skillid,skilllv);
- if(sc_data) {
- if (sc_data[SC_VIOLENTGALE].timer!=-1) limit *= 1.5;
- }
- // check for sc_data first - Celest
- // if (((struct map_session_data *)src)->sc_data[SC_VIOLENTGALE].timer!=-1)
- // limit *= 1.5;
+ if(sc_data && sc_data[SC_VIOLENTGALE].timer!=-1)
+ limit = limit*3/2;
val2=4+skilllv;
- interval=1;
- break;
-
- case AL_PNEUMA: /* ƒjƒ…?ƒ} */
- limit=skill_get_time(skillid,skilllv);
- interval = -1;
- target=(battle_config.defnotenemy)?BCT_NOENEMY:BCT_ALL;
- count = 9;
break;
case AL_WARP: /* ƒ?ƒvƒ|?ƒ^ƒ‹ */
- target=BCT_ALL;
val1=skilllv+6;
if(flag==0)
limit=2000;
- else
- limit=skill_get_time(skillid,skilllv);
+ active_flag=0;
break;
case PR_SANCTUARY: /* ƒTƒ“ƒNƒ`ƒ…ƒAƒŠ */
- count=21;
- limit=skill_get_time(skillid,skilllv);
- val1=skilllv+3;
+ val1=(skilllv+3)*2;
val2=(skilllv>6)?777:skilllv*100;
- target=BCT_ALL;
- range=1;
- break;
-
- case PR_MAGNUS: /* ƒ}ƒOƒkƒXƒGƒNƒ\ƒVƒYƒ€ */
- count=33;
- limit=skill_get_time(skillid,skilllv);
- interval=3000;
+ interval += 500;
break;
case WZ_FIREPILLAR: /* ƒtƒ@ƒCƒA?ƒsƒ‰? */
- if(flag==0)
- limit=skill_get_time(skillid,skilllv);
- else
+ if(flag!=0)
limit=1000;
- interval=2000;
val1=skilllv+2;
- if(skilllv < 6)
- range=1;
- else
- range=2;
- break;
-
- case MG_THUNDERSTORM: /* ƒTƒ“ƒ_?ƒXƒg?ƒ€ */
- limit=500;
- range=1;
- break;
-
- case WZ_FROSTNOVA: /* ƒtƒƒXƒgƒmƒ”ƒ@ */
- limit=500;
- range=5;
- break;
-
- case WZ_HEAVENDRIVE: /* ƒwƒ”ƒ“ƒYƒhƒ‰ƒCƒu */
- limit=500;
- range=2;
- break;
-
- case WZ_METEOR: /* ƒƒeƒIƒXƒg?ƒ€ */
- limit=500;
- range=3;
- break;
-
- case WZ_SIGHTRASHER:
- limit=500;
- count=41;
- break;
-
- case WZ_VERMILION: /* ƒ?ƒhƒIƒuƒ”ƒ@?ƒ~ƒŠƒIƒ“ */
- limit=4100;
- interval=1000;
- range=6;
- break;
-
- case WZ_ICEWALL: /* ƒAƒCƒXƒEƒH?ƒ‹ */
- limit=skill_get_time(skillid,skilllv);
- count=5;
+ if(skilllv >= 6)
+ range=2;
break;
-
- case WZ_STORMGUST: /* ƒXƒg?ƒ€ƒKƒXƒg */
- limit=4600;
- interval=450;
- range=5;
+ case WZ_METEOR:
+ if (skilllv > 10) //L”͈̓ƒeƒI
+ range = 10;
break;
-
- case WZ_QUAGMIRE: /* ƒNƒ@ƒOƒ}ƒCƒA */
- limit=skill_get_time(skillid,skilllv);
- interval=200;
- count=25;
+ case WZ_VERMILION:
+ if (skilllv > 10) //L”͈ÍLOV
+ range = 25;
break;
case HT_SANDMAN: /* ƒTƒ“ƒhƒ}ƒ“ */
case HT_CLAYMORETRAP: /* ƒNƒŒƒCƒ‚ƒA?ƒgƒ‰ƒbƒv */
- limit=skill_get_time(skillid,skilllv);
- range=2;
- break;
case HT_SKIDTRAP: /* ƒXƒLƒbƒhƒgƒ‰ƒbƒv */
case HT_LANDMINE: /* ƒ‰ƒ“ƒhƒ}ƒCƒ“ */
case HT_ANKLESNARE: /* ƒAƒ“ƒNƒ‹ƒXƒlƒA */
- case PF_SPIDERWEB: /* ƒXƒpƒCƒ_?ƒEƒFƒbƒu */
case HT_FLASHER: /* ƒtƒ‰ƒbƒVƒƒ? */
case HT_FREEZINGTRAP: /* ƒtƒŠ?ƒWƒ“ƒOƒgƒ‰ƒbƒv */
case HT_BLASTMINE: /* ƒuƒ‰ƒXƒgƒ}ƒCƒ“ */
- limit=skill_get_time(skillid,skilllv);
- range=1;
+ // longer trap times in WOE [celest]
+ if (map[src->m].flag.gvg) limit *= 4;
break;
-
- case HT_TALKIEBOX: /* ƒg?ƒL?ƒ{ƒbƒNƒX */
- limit=skill_get_time(skillid,skilllv);
- range=1;
- target=BCT_ALL;
- break;
-
case HT_SHOCKWAVE: /* ƒVƒ‡ƒbƒNƒEƒF?ƒuƒgƒ‰ƒbƒv */
- limit=skill_get_time(skillid,skilllv);
- range=1;
val1=skilllv*15+10;
break;
- case AS_VENOMDUST: /* ƒxƒmƒ€ƒ_ƒXƒg */
- limit=skill_get_time(skillid,skilllv);
- interval=1000;
- count=5;
- break;
-
- case CR_GRANDCROSS: /* ƒOƒ‰ƒ“ƒhƒNƒƒX */
- count=29;
- limit=1000;
- interval=300;
- break;
-
- case SA_VOLCANO: /* ƒ{ƒ‹ƒP?ƒm */
- case SA_DELUGE: /* ƒfƒŠƒ…?ƒW */
- case SA_VIOLENTGALE: /* ƒoƒCƒIƒŒƒ“ƒgƒQƒCƒ‹ */
- limit=skill_get_time(skillid,skilllv);
- count=skilllv<=2?25:(skilllv<=4?49:81);
- target=BCT_ALL;
- break;
-
case SA_LANDPROTECTOR: /* ƒOƒ‰ƒ“ƒhƒNƒƒX */
- limit=skill_get_time(skillid,skilllv); // changed to get duration from cast_db (moonsoul)
- val1=skilllv*15+10;
- aoe_diameter=skilllv+skilllv%2+5;
- target=BCT_ALL;
- count=aoe_diameter*aoe_diameter; // -- this will not function if changed to ^2 (moonsoul)
- break;
-
- case BD_LULLABY: /* ŽqŽç‰S */
- case BD_ETERNALCHAOS: /* ƒGƒ^?ƒiƒ‹ƒJƒIƒX */
- case BD_ROKISWEIL: /* ƒƒL‚Ì‹©‚Ñ */
- count=81;
- limit=skill_get_time(skillid,skilllv);
- range=5;
- target=BCT_ALL;
- break;
- case BD_RICHMANKIM:
- case BD_DRUMBATTLEFIELD: /* ?‘¾ŒÛ‚Ì‹¿‚« */
- case BD_RINGNIBELUNGEN: /* ƒj?ƒxƒ‹ƒ“ƒO‚ÌŽw—Ö */
- case BD_INTOABYSS: /* [•£‚Ì’†‚É */
- case BD_SIEGFRIED: /* •sŽ€g‚̃W?ƒNƒtƒŠ?ƒh */
- count=81;
- limit=skill_get_time(skillid,skilllv);
- range=5;
- target=BCT_PARTY;
+ {
+ int aoe_diameter; // -- aoe_diameter (moonsoul) added for sage Area Of Effect skills
+ val1=skilllv*15+10;
+ aoe_diameter=skilllv+skilllv%2+5;
+ count=aoe_diameter*aoe_diameter; // -- this will not function if changed to ^2 (moonsoul)
+ }
break;
case BA_WHISTLE: /* Œû“J */
- count=49;
- limit=skill_get_time(skillid,skilllv);
- range=5;
- target=BCT_NOENEMY;
if(src->type == BL_PC)
val1 = (pc_checkskill((struct map_session_data *)src,BA_MUSICALLESSON)+1)>>1;
- val2 = ((battle_get_agi(src)/10)&0xffff)<<16;
- val2 |= (battle_get_luk(src)/10)&0xffff;
+ val2 = ((status_get_agi(src)/10)&0xffff)<<16;
+ val2 |= (status_get_luk(src)/10)&0xffff;
break;
case DC_HUMMING: /* ƒnƒ~ƒ“ƒO */
- count=49;
- limit=skill_get_time(skillid,skilllv);
- range=5;
- target=BCT_NOENEMY;
if(src->type == BL_PC)
val1 = (pc_checkskill((struct map_session_data *)src,DC_DANCINGLESSON)+1)>>1;
- val2 = battle_get_dex(src)/10;
- break;
-
- case BA_DISSONANCE: /* •s‹¦˜a‰¹ */
- case DC_UGLYDANCE: /* Ž©•ªŸŽè‚ȃ_ƒ“ƒX */
- count=49;
- limit=skill_get_time(skillid,skilllv);
- range=5;
- target=BCT_ENEMY;
+ val2 = status_get_dex(src)/10;
break;
-
case DC_DONTFORGETME: /* Ž„‚ð–Y‚ê‚È‚¢‚Åc */
- count=49;
- limit=skill_get_time(skillid,skilllv);
- range=5;
- target=BCT_ENEMY;
if(src->type == BL_PC)
val1 = (pc_checkskill((struct map_session_data *)src,DC_DANCINGLESSON)+1)>>1;
- val2 = ((battle_get_str(src)/20)&0xffff)<<16;
- val2 |= (battle_get_agi(src)/10)&0xffff;
+ val2 = ((status_get_dex(src)/20)&0xffff)<<16;
+ val2 |= (status_get_agi(src)/10)&0xffff;
break;
case BA_POEMBRAGI: /* ƒuƒ‰ƒM‚ÌŽ */
- count=49;
- limit=skill_get_time(skillid,skilllv);
- range=5;
- target=BCT_NOENEMY;
if(src->type == BL_PC)
val1 = pc_checkskill((struct map_session_data *)src,BA_MUSICALLESSON);
- val2 = ((battle_get_dex(src)/10)&0xffff)<<16;
- val2 |= (battle_get_int(src)/5)&0xffff;
+ val2 = ((status_get_dex(src)/10)&0xffff)<<16;
+ val2 |= (status_get_int(src)/5)&0xffff;
break;
case BA_APPLEIDUN: /* ƒCƒhƒDƒ“‚Ì—ÑŒç */
- count=49;
- limit=skill_get_time(skillid,skilllv);
- range=5;
- target=BCT_NOENEMY;
if(src->type == BL_PC)
- val1 = ((pc_checkskill((struct map_session_data *)src,BA_MUSICALLESSON))&0xffff)<<16;
- else
- val1 = 0;
- val1 |= (battle_get_vit(src))&0xffff;
- val2 = 0;//‰ñ•œ—pƒ^ƒCƒ€ƒJƒEƒ“ƒ^(6•b?‚É1?‰Á)
+ val1 = pc_checkskill((struct map_session_data *)src,BA_MUSICALLESSON)&0xffff;
+ val2 |= (status_get_vit(src))&0xffff;
+ val3 = 0;//‰ñ•œ—pƒ^ƒCƒ€ƒJƒEƒ“ƒ^(6•b?‚É1?‰Á)
break;
case DC_SERVICEFORYOU: /* ƒT?ƒrƒXƒtƒH?ƒ†? */
- count=49;
- limit=skill_get_time(skillid,skilllv);
- range=5;
- target=BCT_PARTY;
if(src->type == BL_PC)
val1 = (pc_checkskill((struct map_session_data *)src,DC_DANCINGLESSON)+1)>>1;
- val2 = battle_get_int(src)/10;
+ val2 = status_get_int(src)/10;
break;
case BA_ASSASSINCROSS: /* —[—z‚̃AƒTƒVƒ“ƒNƒƒX */
- count=49;
- limit=skill_get_time(skillid,skilllv);
- range=5;
- target=BCT_NOENEMY;
if(src->type == BL_PC)
val1 = (pc_checkskill((struct map_session_data *)src,BA_MUSICALLESSON)+1)>>1;
- val2 = battle_get_agi(src)/20;
+ val2 = status_get_agi(src)/20;
break;
case DC_FORTUNEKISS: /* K‰^‚̃LƒX */
- count=49;
- limit=skill_get_time(skillid,skilllv);
- range=5;
- target=BCT_NOENEMY;
if(src->type == BL_PC)
val1 = (pc_checkskill((struct map_session_data *)src,DC_DANCINGLESSON)+1)>>1;
- val2 = battle_get_luk(src)/10;
- break;
-
- case AM_DEMONSTRATION: /* ƒfƒ‚ƒ“ƒXƒgƒŒ?ƒVƒ‡ƒ“ */
- limit=skill_get_time(skillid,skilllv);
- interval=1000;
- range=1;
- target=BCT_ENEMY;
- break;
-
- case WE_CALLPARTNER: /* ‚ ‚È‚½‚Ɉ§‚¢‚½‚¢ */
- limit=skill_get_time(skillid,skilllv);
- range=-1;
- break;
-
- case HP_BASILICA: /* ƒoƒWƒŠƒJ */
- limit=skill_get_time(skillid,skilllv);
- target=BCT_ALL;
- range=3;
- //Fix to prevent the priest from walking while Basilica is up.
- battle_stopwalking(src,1);
- //skill_status_change_start(src,SC_ANKLE,skilllv,0,0,0,limit,0);
- //sd->canmove_tick = gettick() + limit; // added later [celest]
- break;
-
- case PA_GOSPEL: /* ƒSƒXƒyƒ‹ */
- count=49;
- target=BCT_PARTY;
- limit=skill_get_time(skillid,skilllv);
- break;
-
- case CG_MOONLIT:
- range=1;
- target=BCT_ALL;
- limit=skill_get_time(skillid,skilllv);
+ val2 = status_get_luk(src)/10;
break;
case PF_FOGWALL: /* ƒtƒHƒOƒEƒH?ƒ‹ */
- count=15;
- limit=skill_get_time(skillid,skilllv);
- if(sc_data) {
- if (sc_data[SC_DELUGE].timer!=-1) limit *= 2;
- }
+ if(sc_data && sc_data[SC_DELUGE].timer!=-1) limit *= 2;
break;
case RG_GRAFFITI: /* Graffiti */
count=1; // Leave this at 1 [Valaris]
- limit=600000; // Time length [Valaris]
- break;
-
- case GD_LEADERSHIP:
- case GD_GLORYWOUNDS:
- case GD_SOULCOLD:
- case GD_HAWKEYES:
- range=2;
- target=BCT_NOENEMY;
- limit=600000;
break;
}
- nullpo_retr(NULL, group=skill_initunitgroup(src,count,skillid,skilllv,skill_get_unit_id(skillid,flag&1)));
+ nullpo_retr(NULL, group=skill_initunitgroup(src,(count > 0 ? count : layout->count),
+ skillid,skilllv,skill_get_unit_id(skillid,flag&1)));
group->limit=limit;
group->val1=val1;
group->val2=val2;
+ group->val3=val3;
group->target_flag=target;
group->interval=interval;
- group->range=range;
if(skillid==HT_TALKIEBOX ||
skillid==RG_GRAFFITI){
- group->valstr=calloc(80, 1);
+ group->valstr=(char *) aCallocA(80, 1);
if(group->valstr==NULL){
printf("skill_castend_map: out of memory !\n");
exit(1);
}
memcpy(group->valstr,talkie_mes,80);
}
- for(i=0;i<count;i++){
+ for(i=0;i<layout->count;i++){
struct skill_unit *unit;
- int ux=x,uy=y,val1=skilllv,val2=0,limit=group->limit,alive=1;
- int range=group->range;
- switch(skillid){ /* Ý’è */
- case AL_PNEUMA: /* ƒjƒ…?ƒ} */
- {
- static const int dx[9]={-1, 0, 1,-1, 0, 1,-1, 0, 1};
- static const int dy[9]={-1,-1,-1, 0, 0, 0, 1, 1, 1};
- ux+=dx[i];
- uy+=dy[i];
- }
- break;
+ int ux,uy,val1=skilllv,val2=0,limit=group->limit,alive=1;
+ ux = x + layout->dx[i];
+ uy = y + layout->dy[i];
+ switch (skillid) {
case MG_FIREWALL: /* ƒtƒ@ƒCƒ„?ƒEƒH?ƒ‹ */
- {
- if(dir&1){ /* ŽÎ‚ß”z’u */
- static const int dx[][5]={
- { 1,1,0,0,-1 }, { -1,-1,0,0,1 },
- },dy[][5]={
- { 1,0,0,-1,-1 }, { 1,0,0,-1,-1 },
- };
- ux+=dx[(dir>>1)&1][i];
- uy+=dy[(dir>>1)&1][i];
- }else{ /* ㉺”z’u */
- if(dir%4==0) /* ㉺ */
- ux+=i-1;
- else /* ¶‰E */
- uy+=i-1;
- }
- val2=group->val2;
- }
- break;
-
- case PR_SANCTUARY: /* ƒTƒ“ƒNƒ`ƒ…ƒAƒŠ */
- {
- static const int dx[]={
- -1,0,1, -2,-1,0,1,2, -2,-1,0,1,2, -2,-1,0,1,2, -1,0,1 };
- static const int dy[]={
- -2,-2,-2, -1,-1,-1,-1,-1, 0,0,0,0,0, 1,1,1,1,1, 2,2,2, };
- ux+=dx[i];
- uy+=dy[i];
- }
+ val2=group->val2;
break;
-
- case PR_MAGNUS: /* ƒ}ƒOƒkƒXƒGƒNƒ\ƒVƒYƒ€ */
- {
- static const int dx[]={ -1,0,1, -1,0,1, -3,-2,-1,0,1,2,3,
- -3,-2,-1,0,1,2,3, -3,-2,-1,0,1,2,3, -1,0,1, -1,0,1, };
- static const int dy[]={
- -3,-3,-3, -2,-2,-2, -1,-1,-1,-1,-1,-1,-1,
- 0,0,0,0,0,0,0, 1,1,1,1,1,1,1, 2,2,2, 3,3,3 };
- ux+=dx[i];
- uy+=dy[i];
- }
- break;
-
- case WZ_SIGHTRASHER:
- {
- static const int dx[]={
- -5, 0, 5, -4, 0, 4, -3, 0, 3, -2, 0, 2, -1, 0, 1, -5,-4,-3,-2,-1, 0, 1, 2, 3, 4, 5, -1, 0, 1, -2, 0, 2, -3, 0, 3, -4, 0, 4, -5, 0, 5 };
- static const int dy[]={
- -5,-5,-5, -4,-4,-4, -3,-3,-3, -2,-2,-2, -1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5 };
- ux+=dx[i];
- uy+=dy[i];
- }
- break;
-
case WZ_ICEWALL: /* ƒAƒCƒXƒEƒH?ƒ‹ */
- {
- static const int dirx[8]={0,-1,-1,-1,0,1,1,1};
- static const int diry[8]={1,1,0,-1,-1,-1,0,1};
if(skilllv <= 1)
val1 = 500;
else
val1 = 200 + 200*skilllv;
- if(src->x == x && src->y == y)
- dir = 2;
- else
- dir=map_calc_dir(src,x,y);
- ux+=(2-i)*diry[dir];
- uy+=(i-2)*dirx[dir];
- }
- break;
-
- case WZ_QUAGMIRE: /* ƒNƒ@ƒOƒ}ƒCƒA */
- ux+=(i%5-2);
- uy+=(i/5-2);
- if(i==12)
- range=2;
- else
- range=-1;
-
- break;
-
- case AS_VENOMDUST: /* ƒxƒmƒ€ƒ_ƒXƒg */
- {
- static const int dx[]={-1,0,0,0,1};
- static const int dy[]={0,-1,0,1,0};
- ux+=dx[i];
- uy+=dy[i];
- }
- break;
-
- case CR_GRANDCROSS: /* ƒOƒ‰ƒ“ƒhƒNƒƒX */
- {
- static const int dx[]={
- 0, 0, -1,0,1, -2,-1,0,1,2, -4,-3,-2,-1,0,1,2,3,4, -2,-1,0,1,2, -1,0,1, 0, 0, };
- static const int dy[]={
- -4, -3, -2,-2,-2, -1,-1,-1,-1,-1, 0,0,0,0,0,0,0,0,0, 1,1,1,1,1, 2,2,2, 3, 4, };
- ux+=dx[i];
- uy+=dy[i];
- }
- break;
- case SA_VOLCANO: /* ƒ{ƒ‹ƒP?ƒm */
- case SA_DELUGE: /* ƒfƒŠƒ…?ƒW */
- case SA_VIOLENTGALE: /* ƒoƒCƒIƒŒƒ“ƒgƒQƒCƒ‹ */
- {
- int u_range=0,central=0;
- if(skilllv<=2){
- u_range=2;
- central=12;
- }else if(skilllv<=4){
- u_range=3;
- central=24;
- }else if(skilllv>=5){
- u_range=4;
- central=40;
- }
- ux+=(i%(u_range*2+1)-u_range);
- uy+=(i/(u_range*2+1)-u_range);
-
- if(i==central)
- range=u_range;//’†‰›‚̃†ƒjƒbƒg‚Ì?‰Ê”Í?‚Í‘S”Í?
- else
- range=-1;//’†‰›ˆÈŠO‚̃†ƒjƒbƒg‚Íü‚è
- }
- break;
- case SA_LANDPROTECTOR: /* ƒ‰ƒ“ƒhƒvƒƒeƒNƒ^? */
- {
- int u_range=0;
-
- if(skilllv<=2) u_range=3;
- else if(skilllv<=4) u_range=4;
- else if(skilllv>=5) u_range=5;
-
- ux+=(i%(u_range*2+1)-u_range);
- uy+=(i/(u_range*2+1)-u_range);
-
- range=0;
- }
- break;
-
- /* ƒ_ƒ“ƒX‚È‚Ç */
- case BD_LULLABY: /* ŽqŽç‰Ì */
- case BD_RICHMANKIM: /* ƒjƒˆƒ‹ƒh‚̉ƒ */
- case BD_ETERNALCHAOS: /* ‰i‰“‚̬“× */
- case BD_DRUMBATTLEFIELD:/* ?‘¾ŒÛ‚Ì‹¿‚« */
- case BD_RINGNIBELUNGEN: /* ƒj?ƒxƒ‹ƒ“ƒO‚ÌŽw—Ö */
- case BD_ROKISWEIL: /* ƒƒL‚Ì‹©‚Ñ */
- case BD_INTOABYSS: /* [•£‚Ì’†‚É */
- case BD_SIEGFRIED: /* •sŽ€g‚̃W?ƒNƒtƒŠ?ƒh */
- ux+=(i%9-4);
- uy+=(i/9-4);
- if(i==40)
- range=4; /* ’†S‚Ìꇂ͔Í?‚ð4‚ɃI?ƒo?ƒ‰ƒCƒh */
- else
- range=-1; /* ’†S‚¶‚á‚È‚¢ê‡‚Í”Í?‚ð-1‚ɃI?ƒo?ƒ‰ƒCƒh */
- break;
- case BA_DISSONANCE: /* •s‹¦˜a‰¹ */
- case BA_WHISTLE: /* Œû“J */
- case BA_ASSASSINCROSS: /* —[—z‚̃AƒTƒVƒ“ƒNƒƒX */
- case BA_POEMBRAGI: /* ƒuƒ‰ƒM‚ÌŽ */
- case BA_APPLEIDUN: /* ƒCƒhƒDƒ“‚Ì—ÑŒç */
- case DC_UGLYDANCE: /* Ž©•ªŸŽè‚ȃ_ƒ“ƒX */
- case DC_HUMMING: /* ƒnƒ~ƒ“ƒO */
- case DC_DONTFORGETME: /* Ž„‚ð–Y‚ê‚È‚¢‚Åc */
- case DC_FORTUNEKISS: /* K‰^‚̃LƒX */
- case DC_SERVICEFORYOU: /* ƒT?ƒrƒXƒtƒH?ƒ†? */
- case CG_MOONLIT:
- ux+=(i%7-3);
- uy+=(i/7-3);
- if(i==40)
- range=4; /* ’†S‚Ìꇂ͔Í?‚ð4‚ɃI?ƒo?ƒ‰ƒCƒh */
- else
- range=-1; /* ’†S‚¶‚á‚È‚¢ê‡‚Í”Í?‚ð-1‚ɃI?ƒo?ƒ‰ƒCƒh */
- break;
- case PA_GOSPEL: /* ƒSƒXƒyƒ‹ */
- ux+=(i%7-3);
- uy+=(i/7-3);
- break;
- case PF_FOGWALL: /* ƒtƒHƒOƒEƒH?ƒ‹ */
- ux+=(i%5-2);
- uy+=(i/5-1);
break;
case RG_GRAFFITI: /* Graffiti [Valaris] */
ux+=(i%5-2);
@@ -5647,7 +5400,7 @@ struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid,
map_foreachinarea(skill_landprotector,src->m,ux,uy,ux,uy,BL_SKILL,skillid,&alive);
if(skillid==WZ_ICEWALL && alive){
- val2=map_getcell(src->m,ux,uy);
+ val2=map_getcell(src->m,ux,uy,CELL_GETTYPE);
if(val2==5 || val2==1)
alive=0;
else {
@@ -5663,30 +5416,13 @@ struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid,
unit->limit=limit;
unit->range=range;
- // [celest]
- if (sc_data) {
- // attach the unit's id to the caster
- switch (skillid) {
- case HP_BASILICA:
- if (sc_data[SC_BASILICA].timer!=-1)
- sc_data[SC_BASILICA].val4 = (int)unit;
- break;
- case GD_LEADERSHIP:
- sc_data[SC_LEADERSHIP].val4 = (int)unit;
- break;
- case GD_GLORYWOUNDS:
- sc_data[SC_GLORYWOUNDS].val4 = (int)unit;
- break;
- case GD_SOULCOLD:
- sc_data[SC_SOULCOLD].val4 = (int)unit;
- break;
- case GD_HAWKEYES:
- sc_data[SC_HAWKEYES].val4 = (int)unit;
- break;
- }
- }
+ if (range==0 && active_flag)
+ map_foreachinarea(skill_unit_effect,unit->bl.m
+ ,unit->bl.x,unit->bl.y,unit->bl.x,unit->bl.y
+ ,0,&unit->bl,gettick(),1);
}
}
+
return group;
}
@@ -5698,126 +5434,245 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int
{
struct skill_unit_group *sg;
struct block_list *ss;
- struct skill_unit_group_tickset *ts;
- struct map_session_data *srcsd=NULL;
- int diff,goflag,splash_count=0;
+ struct skill_unit *unit2;
+ struct status_change *sc_data;
+ int type;
nullpo_retr(0, src);
nullpo_retr(0, bl);
-
- if( bl->prev==NULL || !src->alive || (bl->type == BL_PC && pc_isdead((struct map_session_data *)bl) ) )
+
+ if(bl->prev==NULL || !src->alive ||
+ (bl->type == BL_PC && pc_isdead((struct map_session_data *)bl)))
return 0;
nullpo_retr(0, sg=src->group);
nullpo_retr(0, ss=map_id2bl(sg->src_id));
+
+ sc_data = status_get_sc_data(bl);
+ type = SkillStatusChangeTable[sg->skill_id];
- if(ss->type == BL_PC)
- nullpo_retr(0, srcsd=(struct map_session_data *)ss);
- if(srcsd && srcsd->chatID)
+ if (battle_check_target(&src->bl,bl,sg->target_flag)<=0)
return 0;
- if( bl->type!=BL_PC && bl->type!=BL_MOB )
+ // ‘ÎÛ‚ªLPã‚É‹‚éꇂ͖³Œø
+ if (map_find_skill_unit_oncell(bl,bl->x,bl->y,SA_LANDPROTECTOR,NULL))
return 0;
- nullpo_retr(0, ts=skill_unitgrouptickset_search( bl, sg->group_id));
- diff=DIFF_TICK(tick,ts->tick);
- goflag=(diff>sg->interval || diff<0);
- if (sg->skill_id == CR_GRANDCROSS && !battle_config.gx_allhit) // d‚È‚Á‚Ä‚¢‚½‚ç3HIT‚µ‚È‚¢
- goflag = (diff>sg->interval*map_count_oncell(bl->m,bl->x,bl->y) || diff<0);
- //?Û‚ªLPã‚É‹‚éꇂ͖³?
- map_foreachinarea(skill_landprotector,bl->m,bl->x,bl->y,bl->x,bl->y,BL_SKILL,0,&goflag);
+ switch (sg->unit_id) {
+ case 0x85: /* ƒjƒ…[ƒ} */
+ case 0x7e: /* ƒZƒCƒtƒeƒBƒEƒH[ƒ‹ */
+ if (sc_data && sc_data[type].timer == -1)
+ status_change_start(bl,type,sg->skill_lv,(int)src,0,0,0,0);
+ break;
- if(!goflag)
- return 0;
- ts->tick=tick;
- ts->group_id=sg->group_id;
+ case 0x80: /* ƒ[ƒvƒ|[ƒ^ƒ‹(”­“®Œã) */
+ if(bl->type==BL_PC){
+ struct map_session_data *sd = (struct map_session_data *)bl;
+ if(sd && src->bl.m == bl->m && src->bl.x == bl->x && src->bl.y == bl->y &&
+ src->bl.x == sd->to_x && src->bl.y == sd->to_y) {
+ if( battle_config.chat_warpportal || !sd->chatID ){
+ pc_setpos(sd,sg->valstr,sg->val2>>16,sg->val2&0xffff,3);
+ if(sg->src_id == bl->id || (strcmp(map[src->bl.m].name,sg->valstr) == 0 &&
+ src->bl.x == (sg->val2>>16) && src->bl.y == (sg->val2&0xffff) ))
+ skill_delunitgroup(sg);
+ if (--sg->val1<=0)
+ skill_delunitgroup(sg);
+ }
+ }
+ } else if(bl->type==BL_MOB && battle_config.mob_warpportal){
+ int m = map_mapname2mapid(sg->valstr);
+ mob_warp((struct mob_data *)bl,m,sg->val2>>16,sg->val2&0xffff,3);
+ }
+ break;
- switch(sg->unit_id){
- case 0x83: /* ƒTƒ“ƒNƒ`ƒ…ƒAƒŠ */
- {
- int race=battle_get_race(bl);
- int damage_flag = (battle_check_undead(race,battle_get_elem_type(bl)) || race == 6)? 1:0;
+ case 0x8e: /* ƒNƒ@ƒOƒ}ƒCƒA */
+ if(bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage )
+ break;
+ if(sc_data && sc_data[type].timer==-1)
+ status_change_start(bl,type,sg->skill_lv,(int)src,0,0,
+ skill_get_time2(sg->skill_id,sg->skill_lv),0);
+ break;
- if( battle_get_hp(bl)>=battle_get_max_hp(bl) && !damage_flag)
+ case 0x9a: /* ƒ{ƒ‹ƒP?ƒm */
+ case 0x9b: /* ƒfƒŠƒ…?ƒW */
+ case 0x9c: /* ƒoƒCƒIƒŒƒ“ƒgƒQƒCƒ‹ */
+ if (sc_data && sc_data[type].timer!=-1) {
+ unit2 = (struct skill_unit *)sc_data[type].val4;
+ if (unit2 && unit2->group &&
+ (unit2==src || DIFF_TICK(sg->tick,unit2->group->tick)<=0))
break;
+ }
+ status_change_start(bl,type,sg->skill_lv,(int)src,0,0,
+ skill_get_time2(sg->skill_id,sg->skill_lv),0);
+ break;
- if((sg->val1--)<=0){
- skill_delunitgroup(sg);
- return 0;
- }
- if(!damage_flag) {
- int heal=sg->val2;
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage)
- heal=0; /* ?‹à峃J?ƒhiƒq?ƒ‹—Ê‚Oj */
- clif_skill_nodamage(&src->bl,bl,AL_HEAL,heal,1);
- battle_heal(NULL,bl,heal,0,0);
- }
- else
- skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
+ case 0x9e: /* ŽqŽç‰S */
+ case 0x9f: /* ƒjƒˆƒ‹ƒh‚̉ƒ */
+ case 0xa0: /* ‰i‰“‚̬“× */
+ case 0xa1: /* ?‘¾ŒÛ‚Ì‹¿‚« */
+ case 0xa2: /* ƒj?ƒxƒ‹ƒ“ƒO‚ÌŽw—Ö */
+ case 0xa3: /* ƒƒL‚Ì‹©‚Ñ */
+ case 0xa4: /* [•£‚Ì’†‚É */
+ case 0xa5: /* •sŽ€g‚̃W?ƒNƒtƒŠ?ƒh */
+ case 0xa6: /* •s‹¦˜a‰¹ */
+ case 0xa7: /* Œû“J */
+ case 0xa8: /* —[—z‚̃AƒTƒVƒ“ƒNƒƒX */
+ case 0xa9: /* ƒuƒ‰ƒM‚ÌŽ */
+ case 0xaa: /* ƒCƒhƒDƒ“‚Ì—ÑŒç */
+ case 0xab: /* Ž©•ªŸŽè‚ȃ_ƒ“ƒX */
+ case 0xac: /* ƒnƒ~ƒ“ƒO */
+ case 0xad: /* Ž„‚ð–Y‚ê‚È‚¢‚Åc */
+ case 0xae: /* K‰^‚̃LƒX */
+ case 0xaf: /* ƒT?ƒrƒXƒtƒH?ƒ†? */
+ if (sg->src_id==bl->id)
+ break;
+ if (sc_data && sc_data[type].timer!=-1) {
+ unit2 = (struct skill_unit *)sc_data[type].val4;
+ if (unit2 && unit2->group &&
+ (unit2 == src || DIFF_TICK(sg->tick,unit2->group->tick)<=0))
+ break;
}
+ status_change_start(bl,type,sg->skill_lv,sg->val1,sg->val2,
+ (int)src,skill_get_time2(sg->skill_id,sg->skill_lv),0);
break;
- case 0x84: /* ƒ}ƒOƒkƒXƒGƒNƒ\ƒVƒYƒ€ */
- {
- int race=battle_get_race(bl);
- int damage_flag = (battle_check_undead(race,battle_get_elem_type(bl)) || race == 6)? 1:0;
+ case 0xb4: // Basilica
+ if (battle_check_target(&src->bl,bl,BCT_NOENEMY)>0) {
+ if (sc_data && sc_data[type].timer!=-1) {
+ struct skill_unit_group *sg2 = (struct skill_unit_group *)sc_data[type].val4;
+ if (sg2 && (sg2 == src->group || DIFF_TICK(sg->tick,sg2->tick)<=0))
+ break;
+ } else
+ status_change_start(bl,type,sg->skill_lv,(int)src,0,0,
+ skill_get_time2(sg->skill_id,sg->skill_lv),0);
+ } else if (!status_get_mode(bl)&0x20)
+ skill_blown(&src->bl,bl,1);
+ break;
- if(!damage_flag)
- return 0;
- skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
+ case 0xb6: /* ƒtƒHƒOƒEƒH?ƒ‹ */
+ if (sc_data && sc_data[type].timer!=-1) {
+ struct skill_unit_group *sg2 = (struct skill_unit_group *)sc_data[type].val4;
+ if (sg2 && (sg2 == src->group || DIFF_TICK(sg->tick,sg2->tick)<=0))
+ break;
}
+ status_change_start (bl, type, sg->skill_lv, sg->val1, sg->val2, (int)sg,
+ skill_get_time2(sg->skill_id, sg->skill_lv), 0);
+ if (battle_check_target(&src->bl,bl,BCT_ENEMY)>0)
+ skill_additional_effect (ss, bl, sg->skill_id, sg->skill_lv, BF_MISC, tick);
+ break;
+
+ case 0xb2: /* ‚ ‚È‚½‚ð_?‚¢‚½‚¢‚Å‚· */
+ case 0xb3: /* ƒSƒXƒyƒ‹ */
+ //‚Ƃ肠‚¦‚¸‰½‚à‚µ‚È‚¢
break;
+ /* default:
+ if(battle_config.error_log)
+ printf("skill_unit_onplace: Unknown skill unit id=%d block=%d\n",sg->unit_id,bl->id);
+ break;*/
+ }
- case 0x85: /* ƒjƒ…?ƒ} */
+ return 0;
+}
+
+/*==========================================
+ * ƒXƒLƒ‹ƒ†ƒjƒbƒg‚Ì”­“®ƒCƒxƒ“ƒg(ƒ^ƒCƒ}[”­“®)
+ *------------------------------------------
+ */
+int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsigned int tick)
+{
+ struct skill_unit_group *sg;
+ struct block_list *ss;
+ int splash_count=0;
+ struct status_change *sc_data;
+ struct skill_unit_group_tickset *ts;
+ int type;
+ int diff=0;
+
+ nullpo_retr(0, src);
+ nullpo_retr(0, bl);
+
+ if (bl->type!=BL_PC && bl->type!=BL_MOB)
+ return 0;
+
+ if (bl->prev==NULL || !src->alive ||
+ (bl->type==BL_PC && pc_isdead((struct map_session_data *)bl)))
+ return 0;
+
+ nullpo_retr(0, sg=src->group);
+ nullpo_retr(0, ss=map_id2bl(sg->src_id));
+ sc_data = status_get_sc_data(bl);
+ type = SkillStatusChangeTable[sg->skill_id];
+
+ // ‘ÎÛ‚ªLPã‚É‹‚éꇂ͖³Œø
+ if (map_find_skill_unit_oncell(bl,bl->x,bl->y,SA_LANDPROTECTOR,NULL))
+ return 0;
+
+ // ‘O‚ɉe‹¿‚ðŽó‚¯‚Ä‚©‚çinterval‚̊Ԃ͉e‹¿‚ðŽó‚¯‚È‚¢
+ nullpo_retr(0,ts = skill_unitgrouptickset_search(bl,sg,tick));
+ diff = DIFF_TICK(tick,ts->tick);
+ if (sg->skill_id == PR_SANCTUARY)
+ diff += 500; // V‹K‚ɉñ•œ‚µ‚½ƒ†ƒjƒbƒg‚¾‚¯ƒJƒEƒ“ƒg‚·‚邽‚߂̎dŠ|‚¯
+ if (diff < 0)
+ return 0;
+ ts->tick = tick+sg->interval;
+ // GX‚Íd‚È‚Á‚Ä‚¢‚½‚ç3HIT‚µ‚È‚¢
+ if (sg->skill_id==CR_GRANDCROSS && !battle_config.gx_allhit)
+ ts->tick += sg->interval*(map_count_oncell(bl->m,bl->x,bl->y)-1);
+
+ switch (sg->unit_id) {
+ case 0x83: /* ƒTƒ“ƒNƒ`ƒ…ƒAƒŠ */
{
- struct skill_unit *unit2;
- struct status_change *sc_data=battle_get_sc_data(bl);
- int type=SC_PNEUMA;
- if(sc_data && sc_data[type].timer==-1)
- skill_status_change_start(bl,type,sg->skill_lv,(int)src,0,0,0,0);
- else if((unit2=(struct skill_unit *)sc_data[type].val2) && unit2 != src ){
- if(DIFF_TICK(sg->tick,unit2->group->tick)>0 )
- skill_status_change_start(bl,type,sg->skill_lv,(int)src,0,0,0,0);
- ts->tick-=sg->interval;
- }
+ int race = status_get_race(bl);
+
+ if (battle_check_undead(race, status_get_elem_type(bl)) || race==6) {
+ if (skill_attack(BF_MAGIC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0)) {
+ // reduce healing count if this was meant for damaging [hekate]
+ sg->val1 -= 2;
+ //sg->val1--; // ƒ`ƒƒƒbƒgƒLƒƒƒ“ƒZƒ‹‚ɑΉž
+ }
+ } else {
+ int heal = sg->val2;
+ if (status_get_hp(bl) >= status_get_max_hp(bl))
+ break;
+ if (bl->type == BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage)
+ heal = 0; /* ‰©‹à峃J[ƒhiƒq[ƒ‹—Ê‚Oj */
+ clif_skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1);
+ battle_heal(NULL, bl, heal, 0, 0);
+ if (diff >= 500)
+ sg->val1--; // V‹K‚É“ü‚Á‚½ƒ†ƒjƒbƒg‚¾‚¯ƒJƒEƒ“ƒg
+ }
+ if (sg->val1 <= 0)
+ skill_delunitgroup(sg);
+ break;
}
- break;
- case 0x7e: /* ƒZƒCƒtƒeƒBƒEƒH?ƒ‹ */
+
+ case 0x84: /* ƒ}ƒOƒkƒXƒGƒNƒ\ƒVƒYƒ€ */
{
- struct skill_unit *unit2;
- struct status_change *sc_data=battle_get_sc_data(bl);
- int type=SC_SAFETYWALL;
- if(sc_data && sc_data[type].timer==-1)
- skill_status_change_start(bl,type,sg->skill_lv,(int)src,0,0,0,0);
- else if((unit2=(struct skill_unit *)sc_data[type].val2) && unit2 != src ){
- if(sg->val1 < unit2->group->val1 )
- skill_status_change_start(bl,type,sg->skill_lv,(int)src,0,0,0,0);
- ts->tick-=sg->interval;
- }
+ int race = status_get_race(bl);
+ if (!battle_check_undead(race,status_get_elem_type(bl)) && race!=6)
+ return 0;
+ skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
+ src->val2++;
+ break;
}
- break;
- case 0x86: /* ƒ?ƒhƒIƒuƒ”ƒ@?ƒ~ƒŠƒIƒ“(•ƒXƒg?ƒ€ƒKƒXƒg •ƒOƒ‰ƒ“ƒhƒNƒƒX) */
+ case 0x7f: /* ƒtƒ@ƒCƒ„[ƒEƒH[ƒ‹ */
skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
- break;
-
- case 0x7f: /* ƒtƒ@ƒCƒ„?ƒEƒH?ƒ‹ */
- if( (src->val2--)>0)
- skill_attack(BF_MAGIC,ss,&src->bl,bl,
- sg->skill_id,sg->skill_lv,tick,0);
- if( src->val2<=0 )
+ if (--src->val2<=0)
skill_delunit(src);
break;
-
- case 0x87: /* ƒtƒ@ƒCƒA?ƒsƒ‰?(?“®‘O) */
+ case 0x86: /* ƒ[ƒhƒIƒuƒ”ƒ@[ƒ~ƒŠƒIƒ“(TS,MS,FN,SG,HD,GX,ˆÅGX) */
+ skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
+ break;
+ case 0x87: /* ƒtƒ@ƒCƒA[ƒsƒ‰[(”­“®‘O) */
skill_delunit(src);
skill_unitsetting(ss,sg->skill_id,sg->skill_lv,src->bl.x,src->bl.y,1);
break;
- case 0x88: /* ƒtƒ@ƒCƒA?ƒsƒ‰?(?“®Œã) */
- if(DIFF_TICK(tick,sg->tick) < 150)
- //skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
- map_foreachinarea(skill_attack_area,bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,0,BF_MAGIC,ss,&src->bl,sg->skill_id,sg->skill_lv,tick,0,BCT_ENEMY); // area damage [Celest]
+ case 0x88: /* ƒtƒ@ƒCƒA[ƒsƒ‰[(”­“®Œã) */
+ map_foreachinarea(skill_attack_area,bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,0,
+ BF_MAGIC,ss,&src->bl,sg->skill_id,sg->skill_lv,tick,0,BCT_ENEMY); // area damage [Celest]
+ //skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
break;
case 0x90: /* ƒXƒLƒbƒhƒgƒ‰ƒbƒv */
@@ -5830,7 +5685,7 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int
clif_changelook(&src->bl,LOOK_BASE,sg->unit_id);
sg->limit=DIFF_TICK(tick,sg->tick)+1500;
}
- break;
+ break;
case 0x93: /* ƒ‰ƒ“ƒhƒ}ƒCƒ“ */
skill_attack(BF_MISC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
@@ -5859,20 +5714,22 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int
break;
case 0x91: /* ƒAƒ“ƒNƒ‹ƒXƒlƒA */
- {
- struct status_change *sc_data=battle_get_sc_data(bl);
- if(sg->val2==0 && sc_data && sc_data[SC_ANKLE].timer==-1){
+ if(sg->val2==0 && sc_data && sc_data[SC_ANKLE].timer==-1){
int moveblock = ( bl->x/BLOCK_SIZE != src->bl.x/BLOCK_SIZE || bl->y/BLOCK_SIZE != src->bl.y/BLOCK_SIZE);
- int sec=skill_get_time2(sg->skill_id,sg->skill_lv) - (double)battle_get_agi(bl)*0.1;
- if(battle_get_mode(bl)&0x20)
- sec = sec/5;
- battle_stopwalking(bl,1);
- skill_status_change_start(bl,SC_ANKLE,sg->skill_lv,0,0,0,sec,0);
-
+ int sec = skill_get_time2(sg->skill_id,sg->skill_lv) - status_get_agi(bl)*100;
+ if(status_get_mode(bl)&0x20)
+ sec = sec/5;
+ if (sec < 3000) // minimum time of 3 seconds [celest]
+ sec = 3000;
+ battle_stopwalking(bl,1);
+ status_change_start(bl,SC_ANKLE,sg->skill_lv,0,0,0,sec,0);
+
+ skill_unit_move(bl,tick,0);
if(moveblock) map_delblock(bl);
bl->x = src->bl.x;
bl->y = src->bl.y;
if(moveblock) map_addblock(bl);
+ skill_unit_move(bl,tick,1);
if(bl->type == BL_MOB)
clif_fixmobpos((struct mob_data *)bl);
else if(bl->type == BL_PET)
@@ -5880,129 +5737,26 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int
else
clif_fixpos(bl);
clif_01ac(&src->bl);
- sg->limit=DIFF_TICK(tick,sg->tick) + sec;
+ sg->limit=DIFF_TICK(tick,sg->tick) + sec;
sg->val2=bl->id;
- }
+ sg->interval = -1;
+ src->range = 0;
}
break;
- case 0x80: /* ƒ?ƒvƒ|?ƒ^ƒ‹(?“®Œã) */
- if(bl->type==BL_PC){
- struct map_session_data *sd = (struct map_session_data *)bl;
- if(sd && src->bl.m == bl->m && src->bl.x == bl->x && src->bl.y == bl->y && src->bl.x == sd->to_x && src->bl.y == sd->to_y) {
- if( battle_config.chat_warpportal || !sd->chatID ){
- if((sg->val1--)>0){
- pc_setpos(sd,sg->valstr,sg->val2>>16,sg->val2&0xffff,3);
- if(sg->src_id == bl->id ||( strcmp(map[src->bl.m].name,sg->valstr) == 0 && src->bl.x == (sg->val2>>16) && src->bl.y == (sg->val2&0xffff) ))
- skill_delunitgroup(sg);
- }else
- skill_delunitgroup(sg);
- }
- }
- }else if(bl->type==BL_MOB && battle_config.mob_warpportal){
- int m=map_mapname2mapid(sg->valstr);
- struct mob_data *md;
- md=(struct mob_data *)bl;
- mob_warp((struct mob_data *)bl,m,sg->val2>>16,sg->val2&0xffff,3);
- }
- break;
-
- case 0x8e: /* ƒNƒ@ƒOƒ}ƒCƒA */
- {
- int type=SkillStatusChangeTable[sg->skill_id];
- if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage )
- break;
- if( battle_get_sc_data(bl)[type].timer==-1 )
- skill_status_change_start(bl,type,sg->skill_lv,(int)src,0,0,skill_get_time2(sg->skill_id,sg->skill_lv),0);
- }
- break;
case 0x92: /* ƒxƒmƒ€ƒ_ƒXƒg */
- {
- struct status_change *sc_data=battle_get_sc_data(bl);
- int type=SkillStatusChangeTable[sg->skill_id];
- if( sc_data && sc_data[type].timer==-1 )
- skill_status_change_start(bl,type,sg->skill_lv,(int)src,0,0,skill_get_time2(sg->skill_id,sg->skill_lv),0);
- }
+ if(sc_data && sc_data[type].timer==-1 )
+ status_change_start(bl,type,sg->skill_lv,(int)src,0,0,skill_get_time2(sg->skill_id,sg->skill_lv),0);
break;
- case 0x9a: /* ƒ{ƒ‹ƒP?ƒm */
- case 0x9b: /* ƒfƒŠƒ…?ƒW */
- case 0x9c: /* ƒoƒCƒIƒŒƒ“ƒgƒQƒCƒ‹ */
- {
- struct skill_unit *unit2;
- struct status_change *sc_data=battle_get_sc_data(bl);
- int type=SkillStatusChangeTable[sg->skill_id];
- if(sc_data && sc_data[type].timer==-1)
- skill_status_change_start(bl,type,sg->skill_lv,(int)src,0,0,skill_get_time2(sg->skill_id,sg->skill_lv),0);
- else if((unit2=(struct skill_unit *)sc_data[type].val2) && unit2 != src ){
- if( DIFF_TICK(sg->tick,unit2->group->tick)>0 )
- skill_status_change_start(bl,type,sg->skill_lv,(int)src,0,0,skill_get_time2(sg->skill_id,sg->skill_lv),0);
- ts->tick-=sg->interval;
- }
- } break;
-
- case 0x9e: /* ŽqŽç‰S */
- case 0x9f: /* ƒjƒˆƒ‹ƒh‚̉ƒ */
- case 0xa0: /* ‰i‰“‚̬“× */
- case 0xa1: /* ?‘¾ŒÛ‚Ì‹¿‚« */
- case 0xa2: /* ƒj?ƒxƒ‹ƒ“ƒO‚ÌŽw—Ö */
- case 0xa3: /* ƒƒL‚Ì‹©‚Ñ */
- case 0xa4: /* [•£‚Ì’†‚É */
- case 0xa5: /* •sŽ€g‚̃W?ƒNƒtƒŠ?ƒh */
- case 0xa6: /* •s‹¦˜a‰¹ */
- case 0xa7: /* Œû“J */
- case 0xa8: /* —[—z‚̃AƒTƒVƒ“ƒNƒƒX */
- case 0xa9: /* ƒuƒ‰ƒM‚ÌŽ */
- case 0xab: /* Ž©•ªŸŽè‚ȃ_ƒ“ƒX */
- case 0xac: /* ƒnƒ~ƒ“ƒO */
- case 0xad: /* Ž„‚ð–Y‚ê‚È‚¢‚Åc */
- case 0xae: /* K‰^‚̃LƒX */
- case 0xaf: /* ƒT?ƒrƒXƒtƒH?ƒ†? */
- case 0xb4:
- case 0xb6: /* ƒtƒHƒOƒEƒH?ƒ‹ */
- {
- struct skill_unit *unit2;
- struct status_change *sc_data=battle_get_sc_data(bl);
- int type=SkillStatusChangeTable[sg->skill_id];
- if(sg->src_id == bl->id)
- break;
- if(sc_data) {
- if (sc_data[type].timer==-1)
- skill_status_change_start(bl,type,sg->skill_lv,sg->val1,sg->val2,
- (int)src,skill_get_time2(sg->skill_id,sg->skill_lv),0);
- else if( (unit2=(struct skill_unit *)sc_data[type].val4) && unit2 != src ){
- if( unit2->group && DIFF_TICK(sg->tick,unit2->group->tick)>0 )
- skill_status_change_start(bl,type,sg->skill_lv,sg->val1,sg->val2,
- (int)src,skill_get_time2(sg->skill_id,sg->skill_lv),0);
- ts->tick-=sg->interval;
- }
- }
- } break;
-
- case 0xaa: /* ƒCƒhƒDƒ“‚Ì—ÑŒç */
- {
- struct skill_unit *unit2;
- struct status_change *sc_data=battle_get_sc_data(bl);
- int type=SkillStatusChangeTable[sg->skill_id];
- if(sg->src_id == bl->id)
- break;
- if( sc_data && sc_data[type].timer==-1)
- skill_status_change_start(bl,type,sg->skill_lv,(sg->val1)>>16,(sg->val1)&0xffff,
- (int)src,skill_get_time2(sg->skill_id,sg->skill_lv),0);
- else if((unit2=(struct skill_unit *)sc_data[type].val4) && unit2 != src ){
- if( DIFF_TICK(sg->tick,unit2->group->tick)>0 )
- skill_status_change_start(bl,type,sg->skill_lv,(sg->val1)>>16,(sg->val1)&0xffff,
- (int)src,skill_get_time2(sg->skill_id,sg->skill_lv),0);
- ts->tick-=sg->interval;
- }
- } break;
case 0xb1: /* ƒfƒ‚ƒ“ƒXƒgƒŒ?ƒVƒ‡ƒ“ */
skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
if(bl->type == BL_PC && rand()%100 < sg->skill_lv && battle_config.equipment_breaking)
pc_breakweapon((struct map_session_data *)bl);
break;
- case 0x99: /* ƒg?ƒL?ƒ{ƒbƒNƒX */
- if(sg->src_id == bl->id) //Ž©•ª‚ª“¥‚ñ‚Å‚à?“®‚µ‚È‚¢
+
+ case 0x99: /* ƒg[ƒL[ƒ{ƒbƒNƒX */
+ if(sg->src_id == bl->id) //Ž©•ª‚ª“¥‚ñ‚Å‚à”­“®‚µ‚È‚¢
break;
if(sg->val2==0){
clif_talkiebox(&src->bl,sg->valstr);
@@ -6011,68 +5765,40 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int
sg->limit=DIFF_TICK(tick,sg->tick)+5000;
sg->val2=-1; //“¥‚ñ‚¾
}
- break;
- case 0xb2: /* ‚ ‚È‚½‚ð_?‚¢‚½‚¢‚Å‚· */
- case 0xb3: /* ƒSƒXƒyƒ‹ */
- //case 0xb6: /* ƒtƒHƒOƒEƒH?ƒ‹ */ - moved [celest]
- //‚Ƃ肠‚¦‚¸‰½‚à‚µ‚È‚¢
+ break;
+
+ // Basilica
+ case 0xb4: /* ƒoƒWƒŠƒJ */
+ if (battle_check_target(&src->bl,bl,BCT_ENEMY)>0 &&
+ !(status_get_mode(bl)&0x20))
+ skill_blown(&src->bl,bl,1);
+ if (sg->src_id==bl->id)
+ break;
+ if (battle_check_target(&src->bl,bl,BCT_NOENEMY)>0 && sc_data && sc_data[type].timer == -1)
+ status_change_start(bl,type,sg->skill_lv,(int)src,0,0,
+ skill_get_time2(sg->skill_id,sg->skill_lv),0);
break;
case 0xb7: /* ƒXƒpƒCƒ_?ƒEƒFƒbƒu */
if(sg->val2==0){
int moveblock = ( bl->x/BLOCK_SIZE != src->bl.x/BLOCK_SIZE || bl->y/BLOCK_SIZE != src->bl.y/BLOCK_SIZE);
skill_additional_effect(ss,bl,sg->skill_id,sg->skill_lv,BF_MISC,tick);
+ skill_unit_move(bl,tick,0);
if(moveblock) map_delblock(bl);
- bl->x = (&src->bl)->x;
- bl->y = (&src->bl)->y;
+ bl->x = src->bl.x;
+ bl->y = src->bl.y;
if(moveblock) map_addblock(bl);
- if(bl->type == BL_MOB)
- clif_fixmobpos((struct mob_data *)bl);
- else if(bl->type == BL_PET)
- clif_fixpetpos((struct pet_data *)bl);
- else
- clif_fixpos(bl);
- clif_01ac(&src->bl);
- sg->limit=DIFF_TICK(tick,sg->tick) + skill_get_time2(sg->skill_id,sg->skill_lv);
+ skill_unit_move(bl,tick,1);
+ if(bl->type == BL_MOB)
+ clif_fixmobpos((struct mob_data *)bl);
+ else if(bl->type == BL_PET)
+ clif_fixpetpos((struct pet_data *)bl);
+ else
+ clif_fixpos(bl);
+ sg->limit = DIFF_TICK(tick,sg->tick)+skill_get_time2(sg->skill_id,sg->skill_lv);
sg->val2=bl->id;
- }
- break;
-
- // New guild skills [Celest]
- case 0xc1: // GD_LEADERSHIP
- {
- struct map_session_data *sd;
- if (srcsd && bl->type == BL_PC && (sd=(struct map_session_data *)bl) &&
- sd->status.guild_id == srcsd->status.guild_id &&
- sd->sc_data[SC_LEADERSHIP].timer == -1 && !sd->sc_data[SC_LEADERSHIP].val4)
- skill_status_change_start(bl,SC_LEADERSHIP,1,0,0,0,0,0 );
- }
- break;
- case 0xc2: // GD_GLORYWOUNDS
- {
- struct map_session_data *sd;
- if (srcsd && bl->type == BL_PC && (sd=(struct map_session_data *)bl) &&
- sd->status.guild_id == srcsd->status.guild_id &&
- sd->sc_data[SC_GLORYWOUNDS].timer == -1 && !sd->sc_data[SC_GLORYWOUNDS].val4)
- skill_status_change_start(bl,SC_GLORYWOUNDS,1,0,0,0,0,0 );
- }
- break;
- case 0xc3: // GD_SOULCOLD
- {
- struct map_session_data *sd;
- if (srcsd && bl->type == BL_PC && (sd=(struct map_session_data *)bl) &&
- sd->status.guild_id == srcsd->status.guild_id &&
- sd->sc_data[SC_SOULCOLD].timer == -1 && !sd->sc_data[SC_SOULCOLD].val4)
- skill_status_change_start(bl,SC_SOULCOLD,1,0,0,0,0,0 );
- }
- break;
- case 0xc4: // GD_HAWKEYES
- {
- struct map_session_data *sd;
- if (srcsd && bl->type == BL_PC && (sd=(struct map_session_data *)bl) &&
- sd->status.guild_id == srcsd->status.guild_id &&
- sd->sc_data[SC_HAWKEYES].timer == -1 && !sd->sc_data[SC_HAWKEYES].val4)
- skill_status_change_start(bl,SC_HAWKEYES,1,0,0,0,0,0 );
+ sg->interval = -1;
+ src->range = 0;
}
break;
@@ -6081,6 +5807,7 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int
printf("skill_unit_onplace: Unknown skill unit id=%d block=%d\n",sg->unit_id,bl->id);
break;*/
}
+
if(bl->type==BL_MOB && ss!=bl) /* ƒXƒLƒ‹Žg—p?Œ‚ÌMOBƒXƒLƒ‹ */
{
if(battle_config.mob_changetarget_byskill == 1)
@@ -6104,85 +5831,55 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int
int skill_unit_onout(struct skill_unit *src,struct block_list *bl,unsigned int tick)
{
struct skill_unit_group *sg;
+ struct status_change *sc_data;
+ int type;
nullpo_retr(0, src);
nullpo_retr(0, bl);
nullpo_retr(0, sg=src->group);
+ sc_data = status_get_sc_data(bl);
+ type = SkillStatusChangeTable[sg->skill_id];
- if( bl->prev==NULL || !src->alive )
- return 0;
-
- if( bl->type!=BL_PC && bl->type!=BL_MOB )
+ if (bl->prev==NULL || !src->alive ||
+ (bl->type == BL_PC && pc_isdead((struct map_session_data *)bl)))
return 0;
switch(sg->unit_id){
- case 0x7e: /* ƒZƒCƒtƒeƒBƒEƒH?ƒ‹ */
- case 0x85: /* ƒjƒ…?ƒ} */
+ case 0x7e: /* ƒZƒCƒtƒeƒBƒEƒH[ƒ‹ */
+ case 0x85: /* ƒjƒ…[ƒ} */
case 0x8e: /* ƒNƒ@ƒOƒ}ƒCƒA */
- {
- struct status_change *sc_data=battle_get_sc_data(bl);
- int type=
- (sg->unit_id==0x85)?SC_PNEUMA:
- ((sg->unit_id==0x7e)?SC_SAFETYWALL:
- SC_QUAGMIRE);
- if((type != SC_QUAGMIRE || bl->type != BL_MOB) &&
- sc_data && sc_data[type].timer!=-1 && ((struct skill_unit *)sc_data[type].val2)==src){
- skill_status_change_end(bl,type,-1);
- }
- } break;
-
- case 0x91: /* ƒAƒ“ƒNƒ‹ƒXƒlƒA */
- {
- struct block_list *target=map_id2bl(sg->val2);
- if( target && target==bl ){
- skill_status_change_end(bl,SC_ANKLE,-1);
- sg->limit=DIFF_TICK(tick,sg->tick)+1000;
- }
- }
- break;
- case 0xb5:
- case 0xb8:
- {
- struct block_list *target=map_id2bl(sg->val2);
- if( target==bl )
- skill_status_change_end(bl,SC_SPIDERWEB,-1);
- sg->limit=DIFF_TICK(tick,sg->tick)+1000;
+ case 0x9a: /* ƒ{ƒ‹ƒP[ƒm */
+ case 0x9b: /* ƒfƒŠƒ…[ƒW */
+ case 0x9c: /* ƒoƒCƒIƒŒƒ“ƒgƒQƒCƒ‹ */
+ if (type==SC_QUAGMIRE && bl->type==BL_MOB)
+ break;
+ if (sc_data && sc_data[type].timer!=-1 && sc_data[type].val2==(int)src) {
+ status_change_end(bl,type,-1);
}
break;
- case 0xb6:
- {
- struct block_list *target=map_id2bl(sg->val2);
- struct status_change *sc_data=battle_get_sc_data(bl);
- if( target==bl ) {
- skill_status_change_end(bl,SC_FOGWALL,-1);
- if (sc_data && sc_data[SC_BLIND].timer!=-1)
- sc_data[SC_BLIND].timer = add_timer(
- gettick() + 30000, skill_status_change_timer, bl->id, 0);
- }
+ case 0x91: /* ƒAƒ“ƒNƒ‹ƒXƒlƒA */
+ {
+ struct block_list *target = map_id2bl(sg->val2);
+ if(target && target == bl){
+ status_change_end(bl,SC_ANKLE,-1);
sg->limit=DIFF_TICK(tick,sg->tick)+1000;
}
break;
- case 0x9a: /* ƒ{ƒ‹ƒP?ƒm */
- case 0x9b: /* ƒfƒŠƒ…?ƒW */
- case 0x9c: /* ƒoƒCƒIƒŒƒ“ƒgƒQƒCƒ‹ */
- {
- struct status_change *sc_data=battle_get_sc_data(bl);
- struct skill_unit *su;
- int type=SkillStatusChangeTable[sg->skill_id];
- if( sc_data && sc_data[type].timer!=-1 && (su=((struct skill_unit *)sc_data[type].val2)) && su == src ){
- skill_status_change_end(bl,type,-1);
- }
- }
- break;
-
+ }
case 0x9e: /* ŽqŽç‰S */
case 0x9f: /* ƒjƒˆƒ‹ƒh‚̉ƒ */
case 0xa0: /* ‰i‰“‚̬“× */
- case 0xa1: /* ?‘¾ŒÛ‚Ì‹¿‚« */
- case 0xa2: /* ƒj?ƒxƒ‹ƒ“ƒO‚ÌŽw—Ö */
+ case 0xa1: /* 푾ŒÛ‚Ì‹¿‚« */
+ case 0xa2: /* ƒj[ƒxƒ‹ƒ“ƒO‚ÌŽw—Ö */
case 0xa3: /* ƒƒL‚Ì‹©‚Ñ */
case 0xa4: /* [•£‚Ì’†‚É */
- case 0xa5: /* •sŽ€g‚̃W?ƒNƒtƒŠ?ƒh */
+ case 0xa5: /* •sŽ€g‚̃W[ƒNƒtƒŠ[ƒh */
+ case 0xad: /* Ž„‚ð–Y‚ê‚È‚¢‚Åc */
+ if (sc_data[type].timer!=-1 && sc_data[type].val4==(int)src) {
+ status_change_end(bl,type,-1);
+ }
+ break;
+
case 0xa6: /* •s‹¦˜a‰¹ */
case 0xa7: /* Œû“J */
case 0xa8: /* —[—z‚̃AƒTƒVƒ“ƒNƒƒX */
@@ -6190,123 +5887,94 @@ int skill_unit_onout(struct skill_unit *src,struct block_list *bl,unsigned int t
case 0xaa: /* ƒCƒhƒDƒ“‚Ì—ÑŒç */
case 0xab: /* Ž©•ªŸŽè‚ȃ_ƒ“ƒX */
case 0xac: /* ƒnƒ~ƒ“ƒO */
- case 0xad: /* Ž„‚ð–Y‚ê‚È‚¢‚Åc */
case 0xae: /* K‰^‚̃LƒX */
case 0xaf: /* ƒT?ƒrƒXƒtƒH?ƒ†? */
- case 0xb4:
- {
- struct status_change *sc_data=battle_get_sc_data(bl);
- struct skill_unit *su;
- int type=SkillStatusChangeTable[sg->skill_id];
- if( sc_data && sc_data[type].timer!=-1 && (su=((struct skill_unit *)sc_data[type].val4)) && su == src ){
- skill_status_change_end(bl,type,-1);
- }
- }
- break;
- case 0xb7: /* ƒXƒpƒCƒ_?ƒEƒFƒbƒu */
- {
- struct block_list *target=map_id2bl(sg->val2);
- if( target && target==bl )
- skill_status_change_end(bl,SC_SPIDERWEB,-1);
- sg->limit=DIFF_TICK(tick,sg->tick)+1000;
+ if (sg->src_id==bl->id) {
+ status_change_end(bl,type,-1);
+ break;
}
- break;
- // New guild skills [Celest]
- case 0xc1: // GD_LEADERSHIP
- {
- struct status_change *sc_data=battle_get_sc_data(bl);
- if (sc_data && sc_data[SC_LEADERSHIP].timer != -1)
- skill_status_change_end(bl,SC_LEADERSHIP,-1);
+ if (sc_data[type].timer!=-1 && sc_data[type].val4==(int)src) {
+ sc_data[type].timer = add_timer(20000+tick, status_change_timer, bl->id, type);
}
- break;
- case 0xc2: // GD_GLORYWOUNDS
- {
- struct status_change *sc_data=battle_get_sc_data(bl);
- if (sc_data && sc_data[SC_GLORYWOUNDS].timer != -1)
- skill_status_change_end(bl,SC_GLORYWOUNDS,-1);
+ break;
+
+ case 0xb4: // Basilica
+ if (sc_data[type].timer!=-1 && sc_data[type].val4==(int)sg) {
+ status_change_end(bl,type,-1);
}
break;
- case 0xc3: // GD_SOULCOLD
+
+ case 0xb6:
{
- struct status_change *sc_data=battle_get_sc_data(bl);
- if (sc_data && sc_data[SC_SOULCOLD].timer != -1)
- skill_status_change_end(bl,SC_SOULCOLD,-1);
+ if (sc_data[type].timer!=-1 && sc_data[type].val4==(int)sg) {
+ status_change_end(bl,SC_FOGWALL,-1);
+ if (sc_data && sc_data[SC_BLIND].timer!=-1)
+ sc_data[SC_BLIND].timer = add_timer(
+ gettick() + 30000, status_change_timer, bl->id, 0);
+ }
+ break;
}
- break;
- case 0xc4: // GD_HAWKEYES
+
+ case 0xb7: /* ƒXƒpƒCƒ_?ƒEƒFƒbƒu */
{
- struct status_change *sc_data=battle_get_sc_data(bl);
- if (sc_data && sc_data[SC_HAWKEYES].timer != -1)
- skill_status_change_end(bl,SC_HAWKEYES,-1);
+ struct block_list *target = map_id2bl(sg->val2);
+ if (target && target==bl)
+ status_change_end(bl,SC_SPIDERWEB,-1);
+ sg->limit = DIFF_TICK(tick,sg->tick)+1000;
+ break;
}
- break;
/* default:
if(battle_config.error_log)
printf("skill_unit_onout: Unknown skill unit id=%d block=%d\n",sg->unit_id,bl->id);
break;*/
}
- skill_unitgrouptickset_delete(bl,sg->group_id);
+
return 0;
}
+
/*==========================================
- * ƒXƒLƒ‹ƒ†ƒjƒbƒg‚Ì휃Cƒxƒ“ƒg
+ * ƒXƒLƒ‹ƒ†ƒjƒbƒgŒø‰Ê”­“®/—£’Eˆ—(foreachinarea)
+ * bl: ƒ†ƒjƒbƒg(BL_PC/BL_MOB)
*------------------------------------------
*/
-int skill_unit_ondelete(struct skill_unit *src,struct block_list *bl,unsigned int tick)
+int skill_unit_effect(struct block_list *bl,va_list ap)
{
- struct skill_unit_group *sg;
+ struct skill_unit *unit;
+ struct skill_unit_group *group;
+ int flag;
+ unsigned int tick;
+ static int called = 0;
- nullpo_retr(0, src);
nullpo_retr(0, bl);
- nullpo_retr(0, sg = src->group);
+ nullpo_retr(0, ap);
+ nullpo_retr(0, unit=va_arg(ap,struct skill_unit*));
+ tick = va_arg(ap,unsigned int);
+ flag = va_arg(ap,unsigned int);
- if( bl->prev==NULL || !src->alive )
+ if (bl->type!=BL_PC && bl->type!=BL_MOB)
return 0;
- if( bl->type!=BL_PC && bl->type!=BL_MOB )
+ if (!unit->alive || bl->prev==NULL)
return 0;
- switch(sg->unit_id){
- case 0x85: /* ƒjƒ…?ƒ} */
- case 0x7e: /* ƒZƒCƒtƒeƒBƒEƒH?ƒ‹ */
- case 0x8e: /* ƒNƒ@ƒOƒ}ƒCƒ„ */
- case 0x9a: /* ƒ{ƒ‹ƒP?ƒm */
- case 0x9b: /* ƒfƒŠƒ…?ƒW */
- case 0x9c: /* ƒoƒCƒIƒŒƒ“ƒgƒQƒCƒ‹ */
- case 0x9e: /* ŽqŽç‰S */
- case 0x9f: /* ƒjƒˆƒ‹ƒh‚̉ƒ */
- case 0xa0: /* ‰i‰“‚̬“× */
- case 0xa1: /* ?‘¾ŒÛ‚Ì‹¿‚« */
- case 0xa2: /* ƒj?ƒxƒ‹ƒ“ƒO‚ÌŽw—Ö */
- case 0xa3: /* ƒƒL‚Ì‹©‚Ñ */
- case 0xa4: /* [•£‚Ì’†‚É */
- case 0xa5: /* •sŽ€g‚̃W?ƒNƒtƒŠ?ƒh */
- case 0xa6: /* •s‹¦˜a‰¹ */
- case 0xa7: /* Œû“J */
- case 0xa8: /* —[—z‚̃AƒTƒVƒ“ƒNƒƒX */
- case 0xa9: /* ƒuƒ‰ƒM‚ÌŽ */
- case 0xaa: /* ƒCƒhƒDƒ“‚Ì—ÑŒç */
- case 0xab: /* Ž©•ªŸŽè‚ȃ_ƒ“ƒX */
- case 0xac: /* ƒnƒ~ƒ“ƒO */
- case 0xad: /* Ž„‚ð–Y‚ê‚È‚¢‚Åc */
- case 0xae: /* K‰^‚̃LƒX */
- case 0xaf: /* ƒT?ƒrƒXƒtƒH?ƒ†? */
- case 0xb4:
- case 0xc1:
- case 0xc2:
- case 0xc3:
- case 0xc4:
- return skill_unit_onout(src,bl,tick);
+ nullpo_retr(0, group=unit->group);
-/* default:
- if(battle_config.error_log)
- printf("skill_unit_ondelete: Unknown skill unit id=%d block=%d\n",sg->unit_id,bl->id);
- break;*/
+ if (flag)
+ skill_unit_onplace(unit,bl,tick);
+ else {
+ skill_unit_onout(unit,bl,tick);
+ unit = map_find_skill_unit_oncell(bl,bl->x,bl->y,group->skill_id,unit);
+ if (unit && called == 0) {
+ called = 1;
+ skill_unit_onplace(unit,bl,tick);
+ called = 0;
+ }
}
- skill_unitgrouptickset_delete(bl,sg->group_id);
+
return 0;
}
+
/*==========================================
* ƒXƒLƒ‹ƒ†ƒjƒbƒg‚ÌŒÀŠEƒCƒxƒ“ƒg
*------------------------------------------
@@ -6314,7 +5982,6 @@ int skill_unit_ondelete(struct skill_unit *src,struct block_list *bl,unsigned in
int skill_unit_onlimit(struct skill_unit *src,unsigned int tick)
{
struct skill_unit_group *sg;
-
nullpo_retr(0, src);
nullpo_retr(0, sg=src->group);
@@ -6326,7 +5993,7 @@ int skill_unit_onlimit(struct skill_unit *src,unsigned int tick)
src->bl.x,src->bl.y,1);
if(group == NULL)
return 0;
- group->valstr=calloc(24, 1);
+ group->valstr=(char *) aCallocA(24, 1);
if(group->valstr==NULL){
printf("skill_unit_onlimit: out of memory !\n");
exit(1);
@@ -6344,7 +6011,7 @@ int skill_unit_onlimit(struct skill_unit *src,unsigned int tick)
{
struct map_session_data *sd = NULL;
struct map_session_data *p_sd = NULL;
- if((sd = (struct map_session_data *)(map_id2bl(sg->src_id))) == NULL)
+ if((sd = map_id2sd(sg->src_id)) == NULL)
return 0;
if((p_sd = pc_get_partner(sd)) == NULL)
return 0;
@@ -6352,38 +6019,6 @@ int skill_unit_onlimit(struct skill_unit *src,unsigned int tick)
pc_setpos(p_sd,map[src->bl.m].name,src->bl.x,src->bl.y,3);
}
break;
- case 0xc1: // GD_LEADERSHIP
- {
- struct map_session_data *sd;
- if ((sd = (struct map_session_data *)(map_id2bl(sg->src_id)))!= NULL) {
- sd->sc_data[SC_LEADERSHIP].val4 = 0;
- }
- }
- break;
- case 0xc2: // GD_GLORYWOUNDS
- {
- struct map_session_data *sd;
- if ((sd = (struct map_session_data *)(map_id2bl(sg->src_id)))!= NULL) {
- sd->sc_data[SC_GLORYWOUNDS].val4 = 0;
- }
- }
- break;
- case 0xc3: // GD_SOULCOLD
- {
- struct map_session_data *sd;
- if ((sd = (struct map_session_data *)(map_id2bl(sg->src_id)))!= NULL) {
- sd->sc_data[SC_SOULCOLD].val4 = 0;
- }
- }
- break;
- case 0xc4: // GD_HAWKEYES
- {
- struct map_session_data *sd;
- if ((sd = (struct map_session_data *)(map_id2bl(sg->src_id)))!= NULL) {
- sd->sc_data[SC_HAWKEYES].val4 = 0;
- }
- }
- break;
}
return 0;
}
@@ -6444,10 +6079,7 @@ int skill_castend_pos( int tid, unsigned int tick, int id,int data )
return 0;
}
- if(battle_config.pc_skill_reiteration == 0) {
- range = -1;
- switch(sd->skillid) {
- case MG_SAFETYWALL:
+ /*case MG_SAFETYWALL:
case WZ_FIREPILLAR:
case HT_SKIDTRAP:
case HT_LANDMINE:
@@ -6460,28 +6092,23 @@ int skill_castend_pos( int tid, unsigned int tick, int id,int data )
case HT_CLAYMORETRAP:
case HT_TALKIEBOX:
case AL_WARP:
- case PF_SPIDERWEB: /* ƒXƒpƒCƒ_?ƒEƒFƒbƒu */
- case RG_GRAFFITI: /* ƒOƒ‰ƒtƒBƒeƒB */
+ case PF_SPIDERWEB:
+ case RG_GRAFFITI:
range = 0;
break;
case AL_PNEUMA:
range = 1;
- break;
- }
- if(range >= 0) {
- if(skill_check_unit_range(sd->bl.m,sd->skillx,sd->skilly,range,sd->skillid) > 0) {
- clif_skill_fail(sd,sd->skillid,0,0);
- sd->canact_tick = tick;
- sd->canmove_tick = tick;
- sd->skillitem = sd->skillitemlv = -1;
- return 0;
- }
- }
+ break;*/
+ if (!battle_config.pc_skill_reiteration &&
+ skill_get_unit_flag(sd->skillid)&UF_NOREITERATION &&
+ skill_check_unit_range(sd->bl.m,sd->skillx,sd->skilly,sd->skillid,sd->skilllv)) {
+ clif_skill_fail(sd,sd->skillid,0,0);
+ sd->canact_tick = tick;
+ sd->canmove_tick = tick;
+ sd->skillitem = sd->skillitemlv = -1;
+ return 0;
}
- if(battle_config.pc_skill_nofootset) {
- range = -1;
- switch(sd->skillid) {
- case WZ_FIREPILLAR:
+ /*case WZ_FIREPILLAR:
case HT_SKIDTRAP:
case HT_LANDMINE:
case HT_ANKLESNARE:
@@ -6492,25 +6119,22 @@ int skill_castend_pos( int tid, unsigned int tick, int id,int data )
case HT_BLASTMINE:
case HT_CLAYMORETRAP:
case HT_TALKIEBOX:
- case PF_SPIDERWEB: /* ƒXƒpƒCƒ_?ƒEƒFƒbƒu */
+ case PF_SPIDERWEB:
case WZ_ICEWALL:
- range = 1;
+ range = 2;
break;
case AL_WARP:
range = 0;
- break;
- }
- if(range >= 0) {
- if(skill_check_unit_range2(sd->bl.m,sd->skillx,sd->skilly,range) > 0) {
- clif_skill_fail(sd,sd->skillid,0,0);
- sd->canact_tick = tick;
- sd->canmove_tick = tick;
- sd->skillitem = sd->skillitemlv = -1;
- return 0;
- }
- }
+ break;*/
+ if (battle_config.pc_skill_nofootset &&
+ skill_get_unit_flag(sd->skillid)&UF_NOFOOTSET &&
+ skill_check_unit_range2(&sd->bl,sd->bl.m,sd->skillx,sd->skilly,sd->skillid,sd->skilllv)) {
+ clif_skill_fail(sd,sd->skillid,0,0);
+ sd->canact_tick = tick;
+ sd->canmove_tick = tick;
+ sd->skillitem = sd->skillitemlv = -1;
+ return 0;
}
-
if(battle_config.pc_land_skill_limit) {
maxcount = skill_get_maxcount(sd->skillid);
if(maxcount > 0) {
@@ -6532,7 +6156,7 @@ int skill_castend_pos( int tid, unsigned int tick, int id,int data )
if(sd->skilllv <= 0) return 0;
range = skill_get_range(sd->skillid,sd->skilllv);
if(range < 0)
- range = battle_get_range(&sd->bl) - (range + 1);
+ range = status_get_range(&sd->bl) - (range + 1);
range += battle_config.pc_skill_add_range;
if(battle_config.skill_out_range_consume) { // changed to allow casting when target walks out of range [Valaris]
if(range < distance(sd->bl.x,sd->bl.y,sd->skillx,sd->skilly)) {
@@ -6589,14 +6213,14 @@ static int skill_check_condition_char_sub(struct block_list *bl,va_list ap)
nullpo_retr(0, c=va_arg(ap,int *));
nullpo_retr(0, ssd=(struct map_session_data*)src);
- s_class = pc_calc_base_job(sd->status.class);
+ s_class = pc_calc_base_job(sd->status.class_);
//ƒ`ƒFƒbƒN‚µ‚È‚¢Ý’è‚È‚çc‚É‚ ‚肦‚È‚¢‘å‚«‚È?Žš‚ð•Ô‚µ‚ÄI—¹
if(!battle_config.player_skill_partner_check){ //–{?‚Íforeach‚Ì‘O‚É‚â‚肽‚¢‚¯‚ÇÝ’è“K—p‰ÓŠ‚ð‚܂Ƃ߂邽‚߂ɂ±‚±‚Ö
(*c)=99;
return 0;
}
- ss_class = pc_calc_base_job(ssd->status.class);
+ ss_class = pc_calc_base_job(ssd->status.class_);
switch(ssd->skillid){
case PR_BENEDICTIO: /* ¹?~•Ÿ */
@@ -6650,24 +6274,25 @@ static int skill_check_condition_use_sub(struct block_list *bl,va_list ap)
nullpo_retr(0, c=va_arg(ap,int *));
nullpo_retr(0, ssd=(struct map_session_data*)src);
- s_class = pc_calc_base_job(sd->status.class);
-
+ s_class = pc_calc_base_job(sd->status.class_);
+
//ƒ`ƒFƒbƒN‚µ‚È‚¢Ý’è‚È‚çc‚É‚ ‚肦‚È‚¢‘å‚«‚È?Žš‚ð•Ô‚µ‚ÄI—¹
if(!battle_config.player_skill_partner_check){ //–{?‚Íforeach‚Ì‘O‚É‚â‚肽‚¢‚¯‚ÇÝ’è“K—p‰ÓŠ‚ð‚܂Ƃ߂邽‚߂ɂ±‚±‚Ö
(*c)=99;
return 0;
}
- ss_class = pc_calc_base_job(ssd->status.class);
+ ss_class = pc_calc_base_job(ssd->status.class_);
skillid=ssd->skillid;
skilllv=ssd->skilllv;
- if(skilllv <= 0) return 0;
+ //if(skilllv <= 0) return 0;
+ if(skillid > 0 && skilllv <= 0) return 0; // celest
switch(skillid){
case PR_BENEDICTIO: /* ¹?~•Ÿ */
if(sd != ssd && (s_class.job == 4 || s_class.job == 8 || s_class.job == 15) &&
(sd->bl.x == ssd->bl.x - 1 || sd->bl.x == ssd->bl.x + 1) && sd->status.sp >= 10){
sd->status.sp -= 10;
- pc_calcstatus(sd,0);
+ status_calc_pc(sd,0);
(*c)++;
}
break;
@@ -6692,7 +6317,7 @@ static int skill_check_condition_use_sub(struct block_list *bl,va_list ap)
){
ssd->sc_data[SC_DANCING].val4=bl->id;
clif_skill_nodamage(bl,src,skillid,skilllv,1);
- skill_status_change_start(bl,SC_DANCING,skillid,ssd->sc_data[SC_DANCING].val2,0,src->id,skill_get_time(skillid,skilllv)+1000,0);
+ status_change_start(bl,SC_DANCING,skillid,ssd->sc_data[SC_DANCING].val2,0,src->id,skill_get_time(skillid,skilllv)+1000,0);
sd->skillid_dance=sd->skillid=skillid;
sd->skilllv_dance=sd->skilllv=skilllv;
(*c)++;
@@ -6718,7 +6343,7 @@ static int skill_check_condition_mob_master_sub(struct block_list *bl,va_list ap
nullpo_retr(0, mob_class=va_arg(ap,int));
nullpo_retr(0, c=va_arg(ap,int *));
- if(md->class==mob_class && md->master_id==src_id)
+ if(md->class_==mob_class && md->master_id==src_id)
(*c)++;
return 0;
}
@@ -6731,6 +6356,7 @@ int skill_check_condition(struct map_session_data *sd,int type)
{
int i,hp,sp,hp_rate,sp_rate,zeny,weapon,state,spiritball,skill,lv,mhp;
int index[10],itemid[10],amount[10];
+ int arrow_flag = 0;
nullpo_retr(0, sd);
@@ -6769,7 +6395,7 @@ int skill_check_condition(struct map_session_data *sd,int type)
clif_skill_fail(sd,sd->skillid,0,0);
return 0;
}
- if(sd->sc_data){
+ if(sd->sc_count){
if( sd->sc_data[SC_DIVINA].timer!=-1 ||
sd->sc_data[SC_ROKISWEIL].timer!=-1 ||
(sd->sc_data[SC_AUTOCOUNTER].timer != -1 && sd->skillid != KN_AUTOCOUNTER) ||
@@ -6778,11 +6404,13 @@ int skill_check_condition(struct map_session_data *sd,int type)
(sd->sc_data[SC_MARIONETTE].timer != -1 && sd->skillid != CG_MARIONETTE)){
clif_skill_fail(sd,sd->skillid,0,0);
return 0; /* ?‘ÔˆÙí‚â’¾?‚È‚Ç */
- }
+ }
}
skill = sd->skillid;
lv = sd->skilllv;
if(lv <= 0) return 0;
+ // for the guild skills [celest]
+ if (skill >= 10000 && skill < 10015) skill-= 9500;
hp=skill_get_hp(skill, lv); /* Á”ïHP */
sp=skill_get_sp(skill, lv); /* Á”ïSP */
if((sd->skillid_old == BD_ENCORE) && skill==sd->skillid_dance)
@@ -6854,6 +6482,10 @@ int skill_check_condition(struct map_session_data *sd,int type)
}
else sd->spiritball_old = lv;
break;
+ case MO_BODYRELOCATION:
+ if (sd->sc_count && sd->sc_data[SC_EXPLOSIONSPIRITS].timer!=-1)
+ spiritball = 0;
+ break;
case MO_CHAINCOMBO: //˜A‘Ŷ
if(sd->sc_data[SC_BLADESTOP].timer==-1){
if(sd->sc_data[SC_COMBO].timer == -1 || sd->sc_data[SC_COMBO].val1 != MO_TRIPLEATTACK)
@@ -6865,7 +6497,7 @@ int skill_check_condition(struct map_session_data *sd,int type)
return 0;
break;
case CH_TIGERFIST: //•šŒÕŒ
- if(sd->sc_data[SC_COMBO].timer == -1 || sd->sc_data[SC_COMBO].val1 != MO_COMBOFINISH)
+ if((sd->sc_data[SC_COMBO].timer == -1 || sd->sc_data[SC_COMBO].val1 != MO_COMBOFINISH) && !sd->state.skill_flag)
return 0;
break;
case CH_CHAINCRUSH: //˜A’Œ•ö?
@@ -6916,8 +6548,9 @@ int skill_check_condition(struct map_session_data *sd,int type)
case AM_SPHEREMINE: /* ƒXƒtƒBƒA?ƒ}ƒCƒ“ */
if(type&1){
int c=0;
- int maxcount=skill_get_maxcount(skill);
- int mob_class=(skill==AM_CANNIBALIZE)?1118:1142;
+ int summons[5] = { 1020, 1068, 1118, 1500, 1368 };
+ int maxcount = (skill==AM_CANNIBALIZE)? 6-lv : skill_get_maxcount(skill);
+ int mob_class = (skill==AM_CANNIBALIZE)? summons[lv-1] :1142;
if(battle_config.pc_land_skill_limit && maxcount>0) {
map_foreachinarea(skill_check_condition_mob_master_sub ,sd->bl.m, 0, 0, map[sd->bl.m].xs, map[sd->bl.m].ys, BL_MOB, sd->bl.id, mob_class,&c );
if(c >= maxcount){
@@ -6929,7 +6562,7 @@ int skill_check_condition(struct map_session_data *sd,int type)
break;
case MG_FIREWALL: /* ƒtƒ@ƒCƒA?ƒEƒH?ƒ‹ */
case WZ_QUAGMIRE:
- case WZ_FIREPILLAR: // celest
+ case WZ_FIREPILLAR: // celest
case PF_FOGWALL:
/* ?§ŒÀ */
if(battle_config.pc_land_skill_limit) {
@@ -6947,6 +6580,29 @@ int skill_check_condition(struct map_session_data *sd,int type)
}
}
break;
+ // skills require arrows as of 12/07 [celest]
+ case AC_DOUBLE:
+ case AC_SHOWER:
+ case AC_CHARGEARROW:
+ case BA_MUSICALSTRIKE:
+ case DC_THROWARROW:
+ case SN_SHARPSHOOTING:
+ case CG_ARROWVULCAN:
+ if(sd->equip_index[10] < 0) {
+ clif_arrow_fail(sd,0);
+ return 0;
+ }
+ arrow_flag = 1;
+ break;
+ case RG_BACKSTAP:
+ if(sd->status.weapon == 11) {
+ if (sd->equip_index[10] < 0) {
+ clif_arrow_fail(sd,0);
+ return 0;
+ }
+ arrow_flag = 1;
+ }
+ break;
}
if(!(type&2)){
@@ -7022,6 +6678,9 @@ int skill_check_condition(struct map_session_data *sd,int type)
}
break;
case ST_EXPLOSIONSPIRITS:
+ if (skill == MO_EXTREMITYFIST && ((sd->sc_data[SC_COMBO].timer != -1 && (sd->sc_data[SC_COMBO].val1 == MO_COMBOFINISH || sd->sc_data[SC_COMBO].val1 == CH_CHAINCRUSH)) || sd->sc_data[SC_BLADESTOP].timer!=-1)) {
+ break;
+ }
if(sd->sc_data[SC_EXPLOSIONSPIRITS].timer == -1) {
clif_skill_fail(sd,skill,0,0);
return 0;
@@ -7043,7 +6702,7 @@ int skill_check_condition(struct map_session_data *sd,int type)
}
break;
case ST_WATER:
- if(map_getcell(sd->bl.m,sd->bl.x,sd->bl.y) != 3 && (sd->sc_data[SC_DELUGE].timer==-1)){ //…ê”»’è
+ if((!map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKWATER))&& (sd->sc_data[SC_DELUGE].timer==-1)){ //…ê”»’è
clif_skill_fail(sd,skill,0,0);
return 0;
}
@@ -7060,8 +6719,9 @@ int skill_check_condition(struct map_session_data *sd,int type)
if(((itemid[i] >= 715 && itemid[i] <= 717) || itemid[i] == 1065) && sd->sc_data[SC_INTOABYSS].timer != -1)
continue;
if(skill == WZ_FIREPILLAR && lv<=5)
- continue; // no gemstones for 1-5 [Celest]
- if(skill == AM_POTIONPITCHER && i != x)
+ continue; // no gemstones for 1-5 [Celest]
+ if((skill == AM_POTIONPITCHER ||
+ skill == CR_SLIMPITCHER) && i != x)
continue;
index[i] = pc_search_inventory(sd,itemid[i]);
@@ -7077,13 +6737,17 @@ int skill_check_condition(struct map_session_data *sd,int type)
if(!(type&1))
return 1;
- if(skill != AM_POTIONPITCHER) {
+ if(skill != AM_POTIONPITCHER &&
+ skill != CR_SLIMPITCHER &&
+ skill != MG_STONECURSE) {
if(skill == AL_WARP && !(type&2))
return 1;
for(i=0;i<10;i++) {
if(index[i] >= 0)
pc_delitem(sd,index[i],amount[i],0); // ƒAƒCƒeƒ€Á”ï
}
+ if (arrow_flag && battle_config.arrow_decrement)
+ pc_delitem(sd,sd->equip_index[10],1,0);
}
if(type&2)
@@ -7112,56 +6776,50 @@ int skill_check_condition(struct map_session_data *sd,int type)
*/
int skill_castfix( struct block_list *bl, int time )
{
- struct map_session_data *sd;
+ struct map_session_data *sd = NULL;
struct mob_data *md; // [Valaris]
struct status_change *sc_data;
- int dex;
int castrate=100;
- int skill,lv,castnodex;
+ int skill,lv;
nullpo_retr(0, bl);
if(bl->type==BL_MOB){ // Crash fix [Valaris]
- md=(struct mob_data*)bl;
+ nullpo_retr(0, md=(struct mob_data*)bl);
skill = md->skillid;
lv = md->skilllv;
- }
-
- else {
- sd=(struct map_session_data*)bl;
+ } else {
+ nullpo_retr(0, sd=(struct map_session_data*)bl);
skill = sd->skillid;
lv = sd->skilllv;
}
if(lv <= 0) return 0;
- sc_data = battle_get_sc_data(bl);
- dex=battle_get_dex(bl);
+ sc_data = status_get_sc_data(bl);
if (skill > MAX_SKILL_DB || skill < 0)
return 0;
- castnodex=skill_get_castnodex(skill, lv);
+ /* ƒTƒtƒ‰ƒMƒEƒ€ */
+ if(sc_data && sc_data[SC_SUFFRAGIUM].timer!=-1 )
+ time=time*(100-sc_data[SC_SUFFRAGIUM].val1*15)/100;
+ status_change_end( bl, SC_SUFFRAGIUM, -1);
if(time==0)
return 0;
- if(castnodex > 0 && bl->type==BL_PC)
- castrate=((struct map_session_data *)bl)->castrate;
- else if (castnodex <= 0 && bl->type==BL_PC) {
- castrate=((struct map_session_data *)bl)->castrate;
- time=time*castrate*(battle_config.castrate_dex_scale - dex)/(battle_config.castrate_dex_scale * 100);
- time=time*battle_config.cast_rate/100;
+ if (sd) {
+ if(!skill_get_castnodex(skill, lv) > 0) {
+ castrate=((struct map_session_data *)bl)->castrate;
+ time=time*castrate*(battle_config.castrate_dex_scale - status_get_dex(bl))/(battle_config.castrate_dex_scale * 100);
+ time=time*battle_config.cast_rate/100;
+ }
}
- /* ƒTƒtƒ‰ƒMƒEƒ€ */
- if(sc_data && sc_data[SC_SUFFRAGIUM].timer!=-1 ){
- time=time*(100-sc_data[SC_SUFFRAGIUM].val1*15)/100;
- skill_status_change_end( bl, SC_SUFFRAGIUM, -1);
- }
/* ƒuƒ‰ƒM‚ÌŽ */
- if(sc_data && sc_data[SC_POEMBRAGI].timer!=-1 )
+ if(sc_data && sc_data[SC_POEMBRAGI].timer!=-1)
time=time*(100-(sc_data[SC_POEMBRAGI].val1*3+sc_data[SC_POEMBRAGI].val2
- +(sc_data[SC_POEMBRAGI].val3>>16)))/100;
+ +(sc_data[SC_POEMBRAGI].val3>>16)))/100;
return (time>0)?time:0;
}
@@ -7172,23 +6830,48 @@ int skill_castfix( struct block_list *bl, int time )
int skill_delayfix( struct block_list *bl, int time )
{
struct status_change *sc_data;
+ struct map_session_data *sd = NULL;
+ int skill = 0,lv = 0;
+ int delayrate = 100;
nullpo_retr(0, bl);
- sc_data = battle_get_sc_data(bl);
- if(time<=0)
- return 0;
+ if(bl->type == BL_PC){
+ nullpo_retr(0, sd = (struct map_session_data*)bl);
+ skill = sd->skillid;
+ lv = sd->skilllv;
+ }
- if(bl->type == BL_PC) {
- if( battle_config.delay_dependon_dex ) /* dex‚̉e‹¿‚ðŒvŽZ‚·‚é */
- time=time*(battle_config.castrate_dex_scale - battle_get_dex(bl))/battle_config.castrate_dex_scale;
- time=time*battle_config.delay_rate/100;
+ if(lv <= 0) return 0;
+
+ sc_data = status_get_sc_data(bl);
+
+ if(sd) {
+ delayrate = sd->delayrate;
+
+ // instant cast attack skills depend on aspd as delay [celest]
+ if (time == 0) {
+ if (skill_db[skill].skill_type == BF_WEAPON)
+ time = status_get_adelay (bl)/2;
+ else
+ time = 300; // default delay, according to official servers
+ } else if (time < 0)
+ time = abs(time) + status_get_adelay (bl)/2; // if set to <0, the aspd delay will be added
+
+ if(battle_config.delay_dependon_dex && /* dex‚̉e‹¿‚ðŒvŽZ‚·‚é */
+ !skill_get_delaynodex(skill, lv)) // if skill casttime is allowed to be reduced by dex
+ time = time * (battle_config.castrate_dex_scale - status_get_dex(bl)) / (battle_config.castrate_dex_scale);
+
+ time = time * delayrate * battle_config.delay_rate / 10000;
+
+ if (time < battle_config.min_skill_delay_limit) // check minimum skill delay
+ time = battle_config.min_skill_delay_limit;
}
/* ƒuƒ‰ƒM‚ÌŽ */
- if(sc_data && sc_data[SC_POEMBRAGI].timer!=-1 )
- time=time*(100-(sc_data[SC_POEMBRAGI].val1*3+sc_data[SC_POEMBRAGI].val2
- +(sc_data[SC_POEMBRAGI].val3&0xffff)))/100;
+ if(sc_data && sc_data[SC_POEMBRAGI].timer != -1 )
+ time = time * (100 - (sc_data[SC_POEMBRAGI].val1 * 3 + sc_data[SC_POEMBRAGI].val2
+ + (sc_data[SC_POEMBRAGI].val3 & 0xffff))) / 100;
return (time>0)?time:0;
}
@@ -7197,128 +6880,97 @@ int skill_delayfix( struct block_list *bl, int time )
* ƒXƒLƒ‹Žg—piIDŽw’èj
*------------------------------------------
*/
-int skill_use_id( struct map_session_data *sd, int target_id,
- int skill_num, int skill_lv)
+int skill_use_id (struct map_session_data *sd, int target_id, int skill_num, int skill_lv)
{
- unsigned int tick;
- int casttime=0,delay=0,skill,range;
- struct map_session_data* target_sd=NULL;
- int forcecast=0;
- struct block_list *bl;
+ int casttime = 0, delay = 0, skill, range;
+ struct map_session_data* tsd = NULL;
+ struct block_list *bl = NULL;
struct status_change *sc_data;
- tick=gettick();
+ int forcecast = 0;
+ unsigned int tick = gettick();
nullpo_retr(0, sd);
- if( (bl=map_id2bl(target_id)) == NULL ){
-/* if(battle_config.error_log)
- printf("skill target not found %d\n",target_id); */
+ if ((bl = map_id2bl(target_id)) == NULL)
return 0;
+ if (bl->type == BL_PC) {
+ nullpo_retr(0, tsd = (struct map_session_data*)bl);
}
if(sd->bl.m != bl->m || pc_isdead(sd))
return 0;
-
if(skillnotok(skill_num, sd)) // [MouseJstr]
return 0;
-
- sc_data=sd->sc_data;
+ if (tsd && skill_num == ALL_RESURRECTION && !pc_isdead(tsd))
+ return 0;
+
+ sc_data = sd->sc_data;
/* ’¾?‚âˆÙíi‚½‚¾‚µAƒOƒŠƒ€‚Ȃǂ̔»’è‚ð‚·‚éj */
- if( sd->opt1>0 )
+ if (sd->opt1 > 0)
return 0;
- if(sd->sc_data){
- if(sc_data[SC_CHASEWALK].timer != -1) return 0;
- if(sc_data[SC_VOLCANO].timer != -1){
- if(skill_num==WZ_ICEWALL) return 0;
- }
- if(sc_data[SC_ROKISWEIL].timer!=-1){
- if(skill_num==BD_ADAPTATION) return 0;
- }
- if( sd->sc_data[SC_DIVINA].timer!=-1 ||
- sd->sc_data[SC_ROKISWEIL].timer!=-1 ||
- (sd->sc_data[SC_AUTOCOUNTER].timer != -1 && sd->skillid != KN_AUTOCOUNTER) ||
- sd->sc_data[SC_STEELBODY].timer != -1 ||
- sd->sc_data[SC_BERSERK].timer != -1 ||
- (sd->sc_data[SC_MARIONETTE].timer != -1 && sd->skillid != CG_MARIONETTE)){
+ if (sc_data) {
+ // allow to use only Chasewalk [celest]
+ if (sc_data[SC_CHASEWALK].timer != -1 && skill_num != ST_CHASEWALK)
+ return 0;
+ if (sc_data[SC_VOLCANO].timer != -1 && skill_num == WZ_ICEWALL)
+ return 0;
+ if (sc_data[SC_ROKISWEIL].timer != -1 && skill_num == BD_ADAPTATION)
+ return 0;
+ if (sc_data[SC_DIVINA].timer != -1 ||
+ sc_data[SC_ROKISWEIL].timer != -1 ||
+ (sc_data[SC_AUTOCOUNTER].timer != -1 && sd->skillid != KN_AUTOCOUNTER) ||
+ sc_data[SC_STEELBODY].timer != -1 ||
+ sc_data[SC_BERSERK].timer != -1 ||
+ (sc_data[SC_MARIONETTE].timer != -1 && sd->skillid != CG_MARIONETTE))
return 0; /* ?‘ÔˆÙí‚â’¾?‚È‚Ç */
+ if (sc_data[SC_BLADESTOP].timer != -1) {
+ if (sc_data[SC_BLADESTOP].val2 == 1) return 0;//”’‰H‚³‚ꂽ‘¤‚Ȃ̂Ń_ƒ
+ switch (sc_data[SC_BLADESTOP].val1) {
+ case 1: return 0;
+ case 2: if (skill_num != MO_FINGEROFFENSIVE) return 0; else break;
+ case 3: if (skill_num != MO_FINGEROFFENSIVE && skill_num != MO_INVESTIGATE) return 0; else break;
+ case 4: if (skill_num != MO_FINGEROFFENSIVE && skill_num != MO_INVESTIGATE && skill_num != MO_CHAINCOMBO) return 0; else break;
+ case 5: if (skill_num != MO_FINGEROFFENSIVE && skill_num != MO_INVESTIGATE && skill_num != MO_CHAINCOMBO && skill_num!=MO_EXTREMITYFIST) return 0; else break;
+ }
}
-
- if(sc_data[SC_BLADESTOP].timer != -1){
- int lv = sc_data[SC_BLADESTOP].val1;
- if(sc_data[SC_BLADESTOP].val2==1) return 0;//”’‰H‚³‚ꂽ‘¤‚Ȃ̂Ń_ƒ
- if(lv==1) return 0;
- if(lv==2 && skill_num!=MO_FINGEROFFENSIVE) return 0;
- if(lv==3 && skill_num!=MO_FINGEROFFENSIVE && skill_num!=MO_INVESTIGATE) return 0;
- if(lv==4 && skill_num!=MO_FINGEROFFENSIVE && skill_num!=MO_INVESTIGATE && skill_num!=MO_CHAINCOMBO) return 0;
- if(lv==5 && skill_num!=MO_FINGEROFFENSIVE && skill_num!=MO_INVESTIGATE && skill_num!=MO_CHAINCOMBO && skill_num!=MO_EXTREMITYFIST) return 0;
- }
-
- if (sd->sc_data[SC_BLOCKSKILL].timer!=-1)
- if (skill_num == sd->sc_data[SC_BLOCKSKILL].val3)
- return 0;
-
if (sc_data[SC_BASILICA].timer != -1) { // Disallow all other skills in Basilica [celest]
- struct skill_unit *su;
- if ((su = (struct skill_unit *)sc_data[SC_BASILICA].val4)) {
- struct skill_unit_group *sg;
- // if caster is the owner of basilica
- if ((sg = su->group) && sg->src_id == sd->bl.id) {
- // skill_status_change_end(&sd->bl,SC_BASILICA,-1);
- // skill_delunitgroup (sg);
- if (skill_num != HP_BASILICA) return 0;
- } // otherwise...
- else
- return 0;
- }
- }
+ struct skill_unit_group *sg = (struct skill_unit_group *)sc_data[SC_BASILICA].val4;
+ // if caster is the owner of basilica
+ if (sg && sg->src_id == sd->bl.id &&
+ skill_num == HP_BASILICA) ; // do nothing
+ // otherwise...
+ else return 0;
+ }
+ /* ‰‰‘t/ƒ_ƒ“ƒX’† */
+ if (sc_data[SC_DANCING].timer != -1) {
+ if (sc_data[SC_DANCING].val4 && skill_num != BD_ADAPTATION) //‡‘t’†‚̓AƒhƒŠƒuˆÈŠO•s‰Â
+ return 0;
+ if (skill_num != BD_ADAPTATION && skill_num != BA_MUSICALSTRIKE && skill_num != DC_THROWARROW)
+ return 0;
+ }
}
- if(sd->status.option&4 && skill_num==TF_HIDING)
+ if (sd->status.option & 4 && skill_num == TF_HIDING)
return 0;
- if(sd->status.option&2 && skill_num!=TF_HIDING && skill_num!=AS_GRIMTOOTH && skill_num!=RG_BACKSTAP && skill_num!=RG_RAID )
+ if (sd->status.option & 2 && skill_num != TF_HIDING && skill_num != AS_GRIMTOOTH && skill_num != RG_BACKSTAP && skill_num != RG_RAID)
return 0;
-
- /*if(map[sd->bl.m].flag.gvg){ //GvG‚ÅŽg—p‚Å‚«‚È‚¢ƒXƒLƒ‹
- switch(skill_num){
- case SM_ENDURE:
- case AL_TELEPORT:
- case AL_WARP:
- case WZ_ICEWALL:
- case TF_BACKSLIDING:
- //case LK_BERSERK: // now usable in WoE - celest
- case HP_BASILICA:
- case HP_ASSUMPTIO:
- case ST_CHASEWALK:
+ if(skill_get_inf2(skill_num) & 0x200 && sd->bl.id == target_id)
return 0;
- }
- }*/
- /* ‰‰‘t/ƒ_ƒ“ƒX’† */
- if( sc_data && sc_data[SC_DANCING].timer!=-1 ){
-// if(battle_config.pc_skill_log)
-// printf("dancing! %d\n",skill_num);
- if( sc_data[SC_DANCING].val4 && skill_num!=BD_ADAPTATION ) //‡‘t’†‚̓AƒhƒŠƒuˆÈŠO•s‰Â
- return 0;
- if(skill_num!=BD_ADAPTATION && skill_num!=BA_MUSICALSTRIKE && skill_num!=DC_THROWARROW){
- return 0;
- }
- }
-
- if(skill_get_inf2(skill_num)&0x200 && sd->bl.id == target_id)
- return 0;
//’¼‘O‚̃XƒLƒ‹‚ª‰½‚©?‚¦‚é•K—v‚Ì‚ ‚éƒXƒLƒ‹
- switch(skill_num){
+ switch (skill_num) {
case SA_CASTCANCEL:
- if(sd->skillid != skill_num){ //ƒLƒƒƒXƒgƒLƒƒƒ“ƒZƒ‹Ž©?‚Í?‚¦‚È‚¢
+ if (sd->skillid != skill_num){ //ƒLƒƒƒXƒgƒLƒƒƒ“ƒZƒ‹Ž©?‚Í?‚¦‚È‚¢
sd->skillid_old = sd->skillid;
sd->skilllv_old = sd->skilllv;
break;
}
+
case BD_ENCORE: /* ƒAƒ“ƒR?ƒ‹ */
- if(!sd->skillid_dance){ //‘O‰ñŽg—p‚µ‚½—x‚肪‚È‚¢‚Æ‚¾‚ß
+ if (!sd->skillid_dance) { //‘O‰ñŽg—p‚µ‚½—x‚肪‚È‚¢‚Æ‚¾‚ß
clif_skill_fail(sd,skill_num,0,0);
return 0;
- }else{
+ } else {
sd->skillid_old = skill_num;
}
break;
@@ -7331,19 +6983,15 @@ int skill_use_id( struct map_session_data *sd, int target_id,
struct guild *g;
if (!sd->status.guild_id)
return 0;
- if (!(g = guild_search(sd->status.guild_id)))
+ if ((g = guild_search(sd->status.guild_id)) == NULL)
return 0;
if (strcmp(sd->status.name,g->master))
return 0;
- if (skill_lv <= 0) skill_lv = 1;
+ skill_lv = guild_checkskill(g, skill_num);
+ if (skill_lv <= 0) return 0;
}
break;
- }
-
- sd->skillid = skill_num;
- sd->skilllv = skill_lv;
- switch(skill_num){ //Ž–‘O‚ɃŒƒxƒ‹‚ª?‚í‚Á‚½‚è‚·‚éƒXƒLƒ‹
case BD_LULLABY: /* ŽqŽç‰Ì */
case BD_RICHMANKIM: /* ƒjƒˆƒ‹ƒh‚̉ƒ */
case BD_ETERNALCHAOS: /* ‰i‰“‚̬“× */
@@ -7355,120 +7003,179 @@ int skill_use_id( struct map_session_data *sd, int target_id,
case BD_RAGNAROK: /* _?‚Ì?¨ */
case CG_MOONLIT: /* ŒŽ–¾‚è‚Ìò‚É—Ž‚¿‚é‰Ô‚Ñ‚ç */
{
- int range=1;
- int c=0;
- map_foreachinarea(skill_check_condition_char_sub,sd->bl.m,
- sd->bl.x-range,sd->bl.y-range,
- sd->bl.x+range,sd->bl.y+range,BL_PC,&sd->bl,&c);
- if(c<1){
+ int range = 1;
+ int c = 0;
+ map_foreachinarea (skill_check_condition_char_sub, sd->bl.m,
+ sd->bl.x-range, sd->bl.y-range,
+ sd->bl.x+range, sd->bl.y+range, BL_PC, &sd->bl, &c);
+ if (c < 1) {
clif_skill_fail(sd,skill_num,0,0);
return 0;
- }else if(c==99){ //‘Š•û•s—vݒ肾‚Á‚½
+ } else if (c == 99) { //‘Š•û•s—vݒ肾‚Á‚½
;
- }else{
- sd->skilllv=(c + skill_lv)/2;
+ } else {
+ sd->skilllv = (c + skill_lv)/2;
}
}
break;
}
- if(!skill_check_condition(sd,0)) return 0;
-
- /* ŽË’ö‚ÆáŠQ•¨ƒ`ƒFƒbƒN */
- range = skill_get_range(skill_num,skill_lv);
- if(range < 0)
- range = battle_get_range(&sd->bl) - (range + 1);
- if(!battle_check_range(&sd->bl,bl,range) )
- return 0;
+ sd->skillid = skill_num;
+ sd->skilllv = skill_lv;
+ if (!skill_check_condition(sd,0)) return 0;
- if(bl->type==BL_PC) {
- target_sd=(struct map_session_data*)bl;
- if(target_sd && skill_num == ALL_RESURRECTION && !pc_isdead(target_sd))
- return 0;
+ {
+ int check_range_flag = 0;
+
+ /* ŽË’ö‚ÆáŠQ•¨ƒ`ƒFƒbƒN */
+ range = skill_get_range(skill_num,skill_lv);
+ if(range < 0)
+ range = status_get_range(&sd->bl) - (range + 1);
+ // be lenient if the skill was cast before we have moved to the correct position [Celest]
+ if (sd->walktimer != -1)
+ range++;
+ else check_range_flag = 1;
+ if(!battle_check_range(&sd->bl,bl,range)) {
+ if (check_range_flag && battle_check_range(&sd->bl,bl,range + 1)) {
+ int mask[8][2] = {{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1}};
+ int dir = map_calc_dir(&sd->bl,bl->x,bl->y);
+ pc_walktoxy (sd, sd->bl.x + mask[dir][0], sd->bl.y + mask[dir][1]);
+ } else
+ return 0;
+ }
}
- if((skill_num != MO_CHAINCOMBO &&
- skill_num != MO_COMBOFINISH &&
- skill_num != MO_EXTREMITYFIST &&
- skill_num != CH_TIGERFIST &&
- skill_num != CH_CHAINCRUSH) ||
+
+ if ((skill_num != MO_CHAINCOMBO &&
+ skill_num != MO_COMBOFINISH &&
+ skill_num != MO_EXTREMITYFIST &&
+ skill_num != CH_TIGERFIST &&
+ skill_num != CH_CHAINCRUSH) ||
+ (skill_num == CH_CHAINCRUSH && sd->state.skill_flag) ||
(skill_num == MO_EXTREMITYFIST && sd->state.skill_flag) )
pc_stopattack(sd);
- casttime=skill_castfix(&sd->bl, skill_get_cast( skill_num,skill_lv) );
- if(skill_num != SA_MAGICROD)
- delay=skill_delayfix(&sd->bl, skill_get_delay( skill_num,skill_lv) );
- //sd->state.skillcastcancel = skill_db[skill_num].castcancel;
+ casttime = skill_castfix(&sd->bl, skill_get_cast(skill_num, skill_lv));
+ if (skill_num != SA_MAGICROD)
+ delay = skill_delayfix(&sd->bl, skill_get_delay(skill_num, skill_lv));
sd->state.skillcastcancel = skill_get_castcancel(skill_num);
- switch(skill_num){ /* ‰½‚©“ÁŽê‚È?—‚ª•K—v */
-// case AL_HEAL: /* ƒq?ƒ‹ */
-// if(battle_check_undead(battle_get_race(bl),battle_get_elem_type(bl)))
-// forcecast=1; /* ƒq?ƒ‹ƒAƒ^ƒbƒN‚È‚ç‰r¥ƒGƒtƒFƒNƒg—L‚è */
-// break;
+ switch (skill_num) { /* ‰½‚©“ÁŽê‚È?—‚ª•K—v */
case ALL_RESURRECTION: /* ƒŠƒUƒŒƒNƒVƒ‡ƒ“ */
- if(bl->type != BL_PC && battle_check_undead(battle_get_race(bl),battle_get_elem_type(bl))){ /* “G‚ªƒAƒ“ƒfƒbƒh‚È‚ç */
- forcecast=1; /* ƒ^?ƒ“ƒAƒ“ƒfƒbƒg‚Æ“¯‚¶‰r¥ŽžŠÔ */
- casttime=skill_castfix(&sd->bl, skill_get_cast(PR_TURNUNDEAD,skill_lv) );
+ if (!tsd && battle_check_undead(status_get_race(bl),status_get_elem_type(bl))) { /* “G‚ªƒAƒ“ƒfƒbƒh‚È‚ç */
+ forcecast = 1; /* ƒ^?ƒ“ƒAƒ“ƒfƒbƒg‚Æ“¯‚¶‰r¥ŽžŠÔ */
+ casttime = skill_castfix(&sd->bl, skill_get_cast(PR_TURNUNDEAD, skill_lv));
}
break;
+
case MO_FINGEROFFENSIVE: /* Žw? */
- casttime += casttime * ((skill_lv > sd->spiritball)? sd->spiritball:skill_lv);
+ casttime += casttime * ((skill_lv > sd->spiritball) ? sd->spiritball : skill_lv);
break;
+
case MO_CHAINCOMBO: /*˜A‘Ŷ*/
target_id = sd->attacktarget;
- if( sc_data && sc_data[SC_BLADESTOP].timer!=-1 ){
+ if (sc_data && sc_data[SC_BLADESTOP].timer != -1){
struct block_list *tbl;
- if((tbl=(struct block_list *)sc_data[SC_BLADESTOP].val4) == NULL) //ƒ^?ƒQƒbƒg‚ª‚¢‚È‚¢H
+ if ((tbl=(struct block_list *)sc_data[SC_BLADESTOP].val4) == NULL) //ƒ^?ƒQƒbƒg‚ª‚¢‚È‚¢H
return 0;
target_id = tbl->id;
}
break;
- case MO_COMBOFINISH: /*–Ò—´Œ*/
- case CH_TIGERFIST: /* •šŒÕŒ */
+ case MO_COMBOFINISH: /*–Ò—´Œ*/
case CH_CHAINCRUSH: /* ˜A’Œ•ö? */
target_id = sd->attacktarget;
break;
+ case CH_TIGERFIST: /* •šŒÕŒ */
+ if (sc_data && sc_data[SC_COMBO].timer != -1 && sc_data[SC_COMBO].val1 == MO_COMBOFINISH)
+ target_id = sd->attacktarget;
+ break;
+
// -- moonsoul (altered to allow proper usage of extremity from new champion combos)
//
case MO_EXTREMITYFIST: /*ˆ¢C—…”e–PŒ*/
- if(sc_data && sc_data[SC_COMBO].timer != -1 && (sc_data[SC_COMBO].val1 == MO_COMBOFINISH || sc_data[SC_COMBO].val1 == CH_CHAINCRUSH)) {
+ if (sc_data && sc_data[SC_COMBO].timer != -1 && (sc_data[SC_COMBO].val1 == MO_COMBOFINISH || sc_data[SC_COMBO].val1 == CH_CHAINCRUSH)) {
casttime = 0;
target_id = sd->attacktarget;
}
- forcecast=1;
+ forcecast = 1;
break;
+
case SA_MAGICROD:
case SA_SPELLBREAKER:
- forcecast=1;
+ forcecast = 1;
break;
+
case WE_MALE:
case WE_FEMALE:
{
- struct map_session_data *p_sd = NULL;
- if((p_sd = pc_get_partner(sd)) == NULL)
+ struct map_session_data *p_sd = pc_get_partner(sd);
+ if (p_sd == NULL)
+ return 0;
+ if (skill_num == WE_MALE && sd->status.hp <= ((15*sd->status.max_hp)/100)) // Requires more than 15% of Max HP for WE_MALE
+ return 0;
+ else if (skill_num == WE_FEMALE && sd->status.sp <= ((15*sd->status.max_sp)/100)) // Requires more than 15% of Max SP for WE_FEMALE
return 0;
target_id = p_sd->bl.id;
//range‚ð‚à‚¤1‰ñ?¸
- range = skill_get_range(skill_num,skill_lv);
- if(range < 0)
- range = battle_get_range(&sd->bl) - (range + 1);
- if(!battle_check_range(&sd->bl,&p_sd->bl,range))
+ if (!battle_check_range(&sd->bl, &p_sd->bl, skill_get_range(skill_num,skill_lv)))
return 0;
}
break;
- case AS_SPLASHER: /* ƒxƒiƒ€ƒXƒvƒ‰ƒbƒVƒƒ? */
+
+ // parent-baby skills
+ case WE_BABY:
+ case WE_CALLPARENT:
+ {
+ struct map_session_data *f_sd = pc_get_father(sd);
+ struct map_session_data *m_sd = pc_get_mother(sd);
+
+ // set target as any one of the parent
+ if (f_sd) target_id = f_sd->bl.id;
+ else if (m_sd) target_id = m_sd->bl.id;
+ else return 0; // neither are found
+
+ // skip range check
+ //range‚ð‚à‚¤1‰ñ?¸
+ //range = skill_get_range(skill_num,skill_lv);
+ //if(!battle_check_range(&sd->bl,&p_sd->bl,range))
+ // return 0;
+ }
+ break;
+
+ case WE_CALLBABY:
{
- struct status_change *t_sc_data = battle_get_sc_data(bl);
- if(t_sc_data && t_sc_data[SC_POISON].timer==-1){
- clif_skill_fail(sd,skill_num,0,10);
+ struct map_session_data *p_sd = pc_get_child(sd);
+ if (p_sd == NULL)
+ return 0;
+ target_id = p_sd->bl.id;
+ //range‚ð‚à‚¤1‰ñ?¸
+ if(!battle_check_range(&sd->bl, &p_sd->bl, skill_get_range(skill_num,skill_lv)))
return 0;
- }
}
break;
- case PF_MEMORIZE: /* ƒƒ‚ƒ‰ƒCƒY */
- casttime = 12000;
+
+ case HP_BASILICA: /* ƒoƒWƒŠƒJ */
+ {
+ if (skill_check_unit_range(sd->bl.m,sd->bl.x,sd->bl.y,sd->skillid,sd->skilllv)) {
+ clif_skill_fail(sd,sd->skillid,0,0);
+ return 0;
+ }
+ if (skill_check_unit_range2(&sd->bl,sd->bl.m,sd->bl.x,sd->bl.y,sd->skillid,sd->skilllv)) {
+ clif_skill_fail(sd,sd->skillid,0,0);
+ return 0;
+ }
+ // cancel Basilica if already in effect
+ if (sc_data && sc_data[SC_BASILICA].timer != -1) {
+ struct skill_unit_group *sg = (struct skill_unit_group *)sd->sc_data[SC_BASILICA].val4;
+ if (sg && sg->src_id == sd->bl.id) {
+ status_change_end(&sd->bl,SC_BASILICA,-1);
+ skill_delunitgroup (sg);
+ return 0;
+ }
+ }
+ }
break;
+
case GD_BATTLEORDER:
case GD_REGENERATION:
case GD_RESTORE:
@@ -7478,62 +7185,52 @@ int skill_use_id( struct map_session_data *sd, int target_id,
}
//ƒƒ‚ƒ‰ƒCƒY?‘Ô‚È‚çƒLƒƒƒXƒgƒ^ƒCƒ€‚ª1/3
- if(sc_data && sc_data[SC_MEMORIZE].timer != -1 && casttime > 0){
+ if (sc_data && sc_data[SC_MEMORIZE].timer != -1 && casttime > 0) {
casttime = casttime/2;
- if((--sc_data[SC_MEMORIZE].val2)<=0)
- skill_status_change_end(&sd->bl, SC_MEMORIZE, -1);
+ if ((--sc_data[SC_MEMORIZE].val2) <= 0)
+ status_change_end(&sd->bl, SC_MEMORIZE, -1);
}
- if(battle_config.pc_skill_log)
- printf("PC %d skill use target_id=%d skill=%d lv=%d cast=%d\n",sd->bl.id,target_id,skill_num,skill_lv,casttime);
+ if (battle_config.pc_skill_log)
+ printf ("PC %d skill use target_id=%d skill=%d lv=%d cast=%d\n",
+ sd->bl.id, target_id, skill_num, skill_lv, casttime);
-// if(sd->skillitem == skill_num)
-// casttime = delay = 0;
-
- if( casttime>0 || forcecast ){ /* ‰r¥‚ª•K—v */
+ if (casttime > 0 || forcecast) { /* ‰r¥‚ª•K—v */
struct mob_data *md;
- clif_skillcasting( &sd->bl, sd->bl.id, target_id, 0,0, skill_num,casttime);
+ clif_skillcasting(&sd->bl, sd->bl.id, target_id, 0,0, skill_num,casttime);
/* ‰r¥”½?ƒ‚ƒ“ƒXƒ^? */
- if( bl->type==BL_MOB && (md=(struct mob_data *)bl) && mob_db[md->class].mode&0x10 &&
- md->state.state!=MS_ATTACK && sd->invincible_timer == -1){
- md->target_id=sd->bl.id;
+ if (bl->type == BL_MOB && (md = (struct mob_data *)bl) && mob_db[md->class_].mode & 0x10 &&
+ md->state.state != MS_ATTACK && sd->invincible_timer == -1){
+ md->target_id = sd->bl.id;
md->state.targettype = ATTACKABLE;
- md->min_chase=13;
+ md->min_chase = 13;
}
}
- if( casttime<=0 ) /* ‰r¥‚Ì–³‚¢‚à‚̂̓Lƒƒƒ“ƒZƒ‹‚³‚ê‚È‚¢ */
- sd->state.skillcastcancel=0;
-
- sd->skilltarget = target_id;
-/* sd->cast_target_bl = bl; */
- sd->skillx = 0;
- sd->skilly = 0;
+ sd->skilltarget = target_id;
+ sd->skillx = 0;
+ sd->skilly = 0;
sd->canact_tick = tick + casttime + delay;
sd->canmove_tick = tick;
- if(!(battle_config.pc_cloak_check_type&2) && sc_data && sc_data[SC_CLOAKING].timer != -1 && sd->skillid != AS_CLOAKING)
- skill_status_change_end(&sd->bl,SC_CLOAKING,-1);
- if(casttime > 0) {
- sd->skilltimer = add_timer( tick+casttime, skill_castend_id, sd->bl.id, 0 );
- if((skill = pc_checkskill(sd,SA_FREECAST)) > 0) {
+
+ if (!(battle_config.pc_cloak_check_type & 2) && sc_data && sc_data[SC_CLOAKING].timer != -1 && sd->skillid != AS_CLOAKING)
+ status_change_end(&sd->bl,SC_CLOAKING,-1);
+ if (casttime > 0) {
+ sd->skilltimer = add_timer (tick + casttime, skill_castend_id, sd->bl.id, 0);
+ if ((skill = pc_checkskill(sd,SA_FREECAST)) > 0) {
sd->prev_speed = sd->speed;
- sd->speed = sd->speed*(175 - skill*5)/100;
- clif_updatestatus(sd,SP_SPEED);
+ status_calc_speed (sd);
}
else
pc_stop_walking(sd,0);
- }
- else {
- if(skill_num != SA_CASTCANCEL)
+ } else {
+ sd->state.skillcastcancel = 0; /* ‰r¥‚Ì–³‚¢‚à‚̂̓Lƒƒƒ“ƒZƒ‹‚³‚ê‚È‚¢ */
+ if (skill_num != SA_CASTCANCEL)
sd->skilltimer = -1;
skill_castend_id(sd->skilltimer,tick,sd->bl.id,0);
}
- //ƒ}ƒWƒbƒNƒpƒ?‚Ì?‰ÊI—¹
- //if(sc_data && sc_data[SC_MAGICPOWER].timer != -1 && skill_num != HW_MAGICPOWER)
- // skill_status_change_end(&sd->bl,SC_MAGICPOWER,-1); // moved
-
return 0;
}
@@ -7541,137 +7238,127 @@ int skill_use_id( struct map_session_data *sd, int target_id,
* ƒXƒLƒ‹Žg—piꊎw’èj
*------------------------------------------
*/
-int skill_use_pos( struct map_session_data *sd,
- int skill_x, int skill_y, int skill_num, int skill_lv)
+int skill_use_pos (struct map_session_data *sd, int skill_x, int skill_y, int skill_num, int skill_lv)
{
struct block_list bl;
struct status_change *sc_data;
- unsigned int tick;
- int casttime=0,delay=0,skill,range;
+ int casttime = 0, delay = 0, skill, range;
+ unsigned int tick = gettick();
nullpo_retr(0, sd);
- if(pc_isdead(sd))
+ if (pc_isdead(sd))
return 0;
-
if (skillnotok(skill_num, sd)) // [MoueJstr]
return 0;
-
- if(skill_num==WZ_ICEWALL && map[sd->bl.m].flag.noicewall && !map[sd->bl.m].flag.pvp) { // noicewall flag [Valaris]
+ if (skill_num == WZ_ICEWALL && map[sd->bl.m].flag.noicewall && !map[sd->bl.m].flag.pvp) { // noicewall flag [Valaris]
clif_skill_fail(sd,sd->skillid,0,0);
return 0;
}
- sc_data=sd->sc_data;
+ sc_data = sd->sc_data;
- if( sd->opt1>0 )
+ if (sd->opt1 > 0)
return 0;
- if(sc_data){
- if( sc_data[SC_DIVINA].timer!=-1 ||
- sc_data[SC_ROKISWEIL].timer!=-1 ||
+ if (sc_data){
+ if (sc_data[SC_DIVINA].timer != -1 ||
+ sc_data[SC_ROKISWEIL].timer != -1 ||
sc_data[SC_AUTOCOUNTER].timer != -1 ||
sc_data[SC_STEELBODY].timer != -1 ||
sc_data[SC_DANCING].timer!=-1 ||
sc_data[SC_BERSERK].timer != -1 ||
- sd->sc_data[SC_MARIONETTE].timer != -1)
+ sc_data[SC_MARIONETTE].timer != -1)
return 0; /* ?‘ÔˆÙí‚â’¾?‚È‚Ç */
- if (sd->sc_data[SC_BLOCKSKILL].timer!=-1)
- if (skill_num == sd->sc_data[SC_BLOCKSKILL].val3)
- return 0;
-
- if (sc_data[SC_BASILICA].timer != -1) { // Basilica cancels if caster moves [celest]
- struct skill_unit *su;
- if ((su = (struct skill_unit *)sc_data[SC_BASILICA].val4)) {
- struct skill_unit_group *sg;
- // if caster is the owner of basilica
- if ((sg = su->group) && sg->src_id == sd->bl.id) {
- // skill_status_change_end(&sd->bl,SC_BASILICA,-1);
- // skill_delunitgroup (sg);
- if (skill_num != HP_BASILICA) return 0;
- } // otherwise...
- else
- return 0;
- }
+ if (sc_data[SC_BASILICA].timer != -1) {
+ struct skill_unit_group *sg = (struct skill_unit_group *)sc_data[SC_BASILICA].val4;
+ // if caster is the owner of basilica
+ if (sg && sg->src_id == sd->bl.id &&
+ skill_num == HP_BASILICA) ; // do nothing
+ // otherwise...
+ else return 0;
}
}
- if(sd->status.option&2)
+ if(sd->status.option & 2)
return 0;
-/* if(map[sd->bl.m].flag.gvg &&
- (skill_num == SM_ENDURE || skill_num == AL_TELEPORT ||
- skill_num == AL_WARP || skill_num == WZ_ICEWALL ||
- skill_num == TF_BACKSLIDING))
- return 0;*/
-
sd->skillid = skill_num;
sd->skilllv = skill_lv;
- if(skill_lv <= 0) return 0;
+ if (skill_lv <= 0) return 0;
sd->skillx = skill_x;
sd->skilly = skill_y;
- if(!skill_check_condition(sd,0)) return 0;
+ if (!skill_check_condition(sd,0)) return 0;
/* ŽË’ö‚ÆáŠQ•¨ƒ`ƒFƒbƒN */
bl.type = BL_NUL;
bl.m = sd->bl.m;
bl.x = skill_x;
bl.y = skill_y;
- range = skill_get_range(skill_num,skill_lv);
- if(range < 0)
- range = battle_get_range(&sd->bl) - (range + 1);
- if(!battle_check_range(&sd->bl,&bl,range) )
- return 0;
+
+ {
+ int check_range_flag = 0;
+
+ /* ŽË’ö‚ÆáŠQ•¨ƒ`ƒFƒbƒN */
+ range = skill_get_range(skill_num,skill_lv);
+ if(range < 0)
+ range = status_get_range(&sd->bl) - (range + 1);
+ // be lenient if the skill was cast before we have moved to the correct position [Celest]
+ if (sd->walktimer != -1)
+ range ++;
+ else check_range_flag = 1;
+ if(!battle_check_range(&sd->bl,&bl,range)) {
+ if (check_range_flag && battle_check_range(&sd->bl,&bl,range + 1)) {
+ int mask[8][2] = {{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1}};
+ int dir = map_calc_dir(&sd->bl,bl.x,bl.y);
+ pc_walktoxy (sd, sd->bl.x + mask[dir][0], sd->bl.y + mask[dir][1]);
+ } else
+ return 0;
+ }
+ }
pc_stopattack(sd);
- casttime=skill_castfix(&sd->bl, skill_get_cast( skill_num,skill_lv) );
- delay=skill_delayfix(&sd->bl, skill_get_delay( skill_num,skill_lv) );
+ casttime = skill_castfix(&sd->bl, skill_get_cast( skill_num,skill_lv) );
+ delay = skill_delayfix(&sd->bl, skill_get_delay( skill_num,skill_lv) );
sd->state.skillcastcancel = skill_db[skill_num].castcancel;
- if(battle_config.pc_skill_log)
- printf("PC %d skill use target_pos=(%d,%d) skill=%d lv=%d cast=%d\n",sd->bl.id,skill_x,skill_y,skill_num,skill_lv,casttime);
+ if (battle_config.pc_skill_log)
+ printf("PC %d skill use target_pos=(%d,%d) skill=%d lv=%d cast=%d\n",
+ sd->bl.id, skill_x, skill_y, skill_num, skill_lv, casttime);
-// if(sd->skillitem == skill_num)
-// casttime = delay = 0;
//ƒƒ‚ƒ‰ƒCƒY?‘Ô‚È‚çƒLƒƒƒXƒgƒ^ƒCƒ€‚ª1/3
- if(sc_data && sc_data[SC_MEMORIZE].timer != -1 && casttime > 0){
+ if (sc_data && sc_data[SC_MEMORIZE].timer != -1 && casttime > 0){
casttime = casttime/3;
- if((--sc_data[SC_MEMORIZE].val2)<=0)
- skill_status_change_end(&sd->bl, SC_MEMORIZE, -1);
+ if ((--sc_data[SC_MEMORIZE].val2)<=0)
+ status_change_end(&sd->bl, SC_MEMORIZE, -1);
}
- if( casttime>0 ) /* ‰r¥‚ª•K—v */
- clif_skillcasting( &sd->bl,
- sd->bl.id, 0, skill_x,skill_y, skill_num,casttime);
-
- if( casttime<=0 ) /* ‰r¥‚Ì–³‚¢‚à‚̂̓Lƒƒƒ“ƒZƒ‹‚³‚ê‚È‚¢ */
- sd->state.skillcastcancel=0;
-
+ if (casttime > 0) /* ‰r¥‚ª•K—v */
+ clif_skillcasting(&sd->bl, sd->bl.id, 0, skill_x, skill_y, skill_num, casttime);
+
sd->skilltarget = 0;
-/* sd->cast_target_bl = NULL; */
- tick=gettick();
sd->canact_tick = tick + casttime + delay;
sd->canmove_tick = tick;
- if(!(battle_config.pc_cloak_check_type&2) && sc_data && sc_data[SC_CLOAKING].timer != -1)
- skill_status_change_end(&sd->bl,SC_CLOAKING,-1);
- if(casttime > 0) {
- sd->skilltimer = add_timer( tick+casttime, skill_castend_pos, sd->bl.id, 0 );
- if((skill = pc_checkskill(sd,SA_FREECAST)) > 0) {
+ if (!(battle_config.pc_cloak_check_type&2) && sc_data && sc_data[SC_CLOAKING].timer != -1)
+ status_change_end(&sd->bl,SC_CLOAKING,-1);
+ if (casttime > 0) {
+ sd->skilltimer = add_timer(tick + casttime, skill_castend_pos, sd->bl.id, 0);
+ if ((skill = pc_checkskill(sd,SA_FREECAST)) > 0) {
sd->prev_speed = sd->speed;
- sd->speed = sd->speed*(175 - skill*5)/100;
- clif_updatestatus(sd,SP_SPEED);
+ status_calc_speed (sd);
}
else
pc_stop_walking(sd,0);
- }
- else {
+ } else {
+ sd->state.skillcastcancel = 0; /* ‰r¥‚Ì–³‚¢‚à‚̂̓Lƒƒƒ“ƒZƒ‹‚³‚ê‚È‚¢ */
sd->skilltimer = -1;
skill_castend_pos(sd->skilltimer,tick,sd->bl.id,0);
}
//ƒ}ƒWƒbƒNƒpƒ?‚Ì?‰ÊI—¹
- if(sc_data && sc_data[SC_MAGICPOWER].timer != -1 && skill_num != HW_MAGICPOWER)
- skill_status_change_end(&sd->bl,SC_MAGICPOWER,-1);
+ if (skill_get_unit_id(skill_num, 0) != 0x86 &&
+ sc_data && sc_data[SC_MAGICPOWER].timer != -1)
+ status_change_end(&sd->bl,SC_MAGICPOWER,-1);
return 0;
}
@@ -7680,60 +7367,59 @@ int skill_use_pos( struct map_session_data *sd,
* ƒXƒLƒ‹‰r¥ƒLƒƒƒ“ƒZƒ‹
*------------------------------------------
*/
-int skill_castcancel(struct block_list *bl,int type)
+int skill_castcancel (struct block_list *bl, int type)
{
int inf;
- int ret=0;
+ int ret = 0;
nullpo_retr(0, bl);
- if(bl->type==BL_PC){
- struct map_session_data *sd=(struct map_session_data *)bl;
- unsigned long tick=gettick();
+ if (bl->type == BL_PC) {
+ struct map_session_data *sd = (struct map_session_data *)bl;
+ unsigned long tick = gettick();
nullpo_retr(0, sd);
- sd->canact_tick=tick;
+ sd->canact_tick = tick;
sd->canmove_tick = tick;
- if( sd->skilltimer!=-1){
- if(pc_checkskill(sd,SA_FREECAST) > 0) {
+ if (sd->skilltimer != -1) {
+ if (pc_checkskill(sd,SA_FREECAST) > 0) {
sd->speed = sd->prev_speed;
clif_updatestatus(sd,SP_SPEED);
}
- if(!type) {
- if((inf = skill_get_inf( sd->skillid )) == 2 || inf == 32)
- ret=delete_timer( sd->skilltimer, skill_castend_pos );
+ if (!type) {
+ if ((inf = skill_get_inf( sd->skillid )) == 2 || inf == 32)
+ ret = delete_timer( sd->skilltimer, skill_castend_pos );
else
ret=delete_timer( sd->skilltimer, skill_castend_id );
- if(ret<0)
- printf("delete timer error : skillid : %d\n",sd->skillid);
- }
- else {
- if((inf = skill_get_inf( sd->skillid_old )) == 2 || inf == 32)
- ret=delete_timer( sd->skilltimer, skill_castend_pos );
+ if (ret < 0)
+ printf("delete timer error : skillid : %d\n", sd->skillid);
+ } else {
+ if ((inf = skill_get_inf( sd->skillid_old )) == 2 || inf == 32)
+ ret = delete_timer( sd->skilltimer, skill_castend_pos );
else
- ret=delete_timer( sd->skilltimer, skill_castend_id );
- if(ret<0)
- printf("delete timer error : skillid : %d\n",sd->skillid_old);
+ ret = delete_timer( sd->skilltimer, skill_castend_id );
+ if (ret < 0)
+ printf("delete timer error : skillid : %d\n", sd->skillid_old);
}
- sd->skilltimer=-1;
+ sd->skilltimer = -1;
clif_skillcastcancel(bl);
}
-
return 0;
- }else if(bl->type==BL_MOB){
- struct mob_data *md=(struct mob_data *)bl;
+ } else if (bl->type == BL_MOB) {
+ struct mob_data *md = (struct mob_data *)bl;
nullpo_retr(0, md);
- if( md->skilltimer!=-1 ){
- if((inf = skill_get_inf( md->skillid )) == 2 || inf == 32)
- ret=delete_timer( md->skilltimer, mobskill_castend_pos );
+ if (md->skilltimer != -1) {
+ if ((inf = skill_get_inf( md->skillid )) == 2 || inf == 32)
+ ret = delete_timer( md->skilltimer, mobskill_castend_pos );
else
- ret=delete_timer( md->skilltimer, mobskill_castend_id );
- md->skilltimer=-1;
+ ret = delete_timer( md->skilltimer, mobskill_castend_id );
+ md->skilltimer = -1;
clif_skillcastcancel(bl);
}
- if(ret<0)
- printf("delete timer error : skillid : %d\n",md->skillid);
+ if (ret < 0)
+ printf("delete timer error : skillid : %d\n", md->skillid);
return 0;
}
+
return 1;
}
/*=========================================
@@ -7912,13 +7598,14 @@ int skill_devotion3(struct block_list *bl,int target)
int n,r=0;
nullpo_retr(1, bl);
+ md = (struct map_session_data *)bl;
- if( (md = (struct map_session_data *)bl) == NULL || (sd = map_id2sd(target)) == NULL )
+ if ((sd = map_id2sd(target))==NULL)
return 1;
else
r = distance(bl->x,bl->y,sd->bl.x,sd->bl.y);
- if(pc_checkskill(sd,CR_DEVOTION)+6 < r){ // ‹–—e”Í?‚ð’´‚¦‚Ä‚½
+ if(pc_checkskill(md,CR_DEVOTION)+6 < r){ // ‹–—e”Í?‚ð’´‚¦‚Ä‚½
for(n=0;n<5;n++)
if(md->dev.val1[n]==target)
md->dev.val2[n]=0; // —£‚ê‚½Žž‚ÍA?‚ð؂邾‚¯
@@ -7936,7 +7623,7 @@ void skill_devotion_end(struct map_session_data *md,struct map_session_data *sd,
md->dev.val1[target]=md->dev.val2[target]=0;
if(sd && sd->sc_data){
- // skill_status_change_end(sd->bl,SC_DEVOTION,-1);
+ // status_change_end(sd->bl,SC_DEVOTION,-1);
sd->sc_data[SC_DEVOTION].val1=0;
sd->sc_data[SC_DEVOTION].val2=0;
clif_status_change(&sd->bl,SC_DEVOTION,0);
@@ -7978,7 +7665,7 @@ int skill_autospell(struct map_session_data *sd,int skillid)
if(maxlv > (lv=pc_checkskill(sd,skillid)))
maxlv = lv;
- skill_status_change_start(&sd->bl,SC_AUTOSPELL,skilllv,skillid,maxlv,0, // val1:ƒXƒLƒ‹ID val2:Žg—pÅ‘åLv
+ status_change_start(&sd->bl,SC_AUTOSPELL,skilllv,skillid,maxlv,0, // val1:ƒXƒLƒ‹ID val2:Žg—pÅ‘åLv
skill_get_time(SA_AUTOSPELL,skilllv),0);// ‚É‚µ‚Ă݂½‚¯‚Çbscript‚ª‘‚«ˆÕ‚¢???H
return 0;
}
@@ -8087,34 +7774,64 @@ int skill_frostjoke_scream(struct block_list *bl,va_list ap)
if(src == bl)//Ž©•ª‚É‚Í?‚©‚È‚¢
return 0;
- if(battle_check_target(src,bl,BCT_ENEMY) > 0)
+ if (map[src->m].flag.gvg || map[src->m].flag.pvp)
skill_additional_effect(src,bl,skillnum,skilllv,BF_MISC,tick);
- else if(battle_check_target(src,bl,BCT_PARTY) > 0) {
- if(rand()%100 < 10)//PTƒƒ“ƒo‚É‚à’áŠm—¦‚Å‚©‚©‚é(‚Ƃ肠‚¦‚¸10%)
+ // we freeze everybody except of ourselfes on pvp/gvg [veider]
+ else {
+ if(battle_check_target(src,bl,BCT_ENEMY) > 0)
+ skill_additional_effect(src,bl,skillnum,skilllv,BF_MISC,tick);
+ else if(battle_check_target(src,bl,BCT_PARTY) > 0 && rand()%100 < 10)
skill_additional_effect(src,bl,skillnum,skilllv,BF_MISC,tick);
}
+ // so on non-pvp/gvg we are just freezing as freezed before
return 0;
}
/*==========================================
- *ƒAƒuƒ‰ƒJƒ_ƒuƒ‰‚ÌŽg—pƒXƒLƒ‹Œˆ’è(Œˆ’èƒXƒLƒ‹‚ªƒ_ƒ‚È‚ç0‚ð•Ô‚·)
+ * Moonlit creates a 'safe zone' [celest]
*------------------------------------------
*/
-int skill_abra_dataset(int skilllv)
+static int skill_moonlit_count(struct block_list *bl,va_list ap)
{
- int skill = rand()%331;
+ int *c, id;
+ struct map_session_data *sd;
- if(skilllv <= 0) return 0;
+ nullpo_retr(0, bl);
+ nullpo_retr(0, ap);
+ nullpo_retr(0, (sd=(struct map_session_data *)bl));
- //db‚ÉŠî‚­ƒŒƒxƒ‹?Šm—¦”»’è
- if(skill_abra_db[skill].req_lv > skilllv || rand()%10000 >= skill_abra_db[skill].per) return 0;
- //NPCƒXƒLƒ‹‚̓_ƒ
- if(skill >= NPC_PIERCINGATT && skill <= NPC_SUMMONMONSTER) return 0;
- //‰‰‘tƒXƒLƒ‹‚̓_ƒ
- if(skill_is_danceskill(skill)) return 0;
+ id=va_arg(ap,int);
+ c=va_arg(ap,int *);
- return skill;
+ if (sd->bl.id != id && sd->sc_count && sd->sc_data[SC_MOONLIT].timer != -1 && c)
+ (*c)++;
+ return 0;
+}
+
+int skill_check_moonlit (struct block_list *bl, int dx, int dy)
+{
+ int c=0;
+ nullpo_retr(0, bl);
+ map_foreachinarea(skill_moonlit_count,bl->m,
+ dx-1,dy-1,dx+1,dy+1,BL_PC,bl->id,&c);
+ return (c>0);
+}
+
+/*==========================================
+ * ƒoƒWƒŠƒJ‚̃Zƒ‹‚ðÝ’è‚·‚é
+ *------------------------------------------
+ */
+void skill_basilica_cell(struct skill_unit *unit,int flag)
+{
+ int i,x,y,range = skill_get_unit_range(HP_BASILICA);
+ int size = range*2+1;
+
+ for (i=0;i<size*size;i++) {
+ x = unit->bl.x+(i%size-range);
+ y = unit->bl.y+(i/size-range);
+ map_setcell(unit->bl.m,x,y,flag);
+ }
}
/*==========================================
@@ -8137,7 +7854,8 @@ int skill_attack_area(struct block_list *bl,va_list ap)
return 0;
skillid=va_arg(ap,int);
skilllv=va_arg(ap,int);
- if(skilllv <= 0) return 0;
+ //if(skilllv <= 0) return 0;
+ if(skillid > 0 && skilllv <= 0) return 0; // celest
tick=va_arg(ap,unsigned int);
flag=va_arg(ap,int);
type=va_arg(ap,int);
@@ -8155,16 +7873,20 @@ int skill_clear_element_field(struct block_list *bl)
{
struct mob_data *md=NULL;
struct map_session_data *sd=NULL;
- int i,skillid;
+ int i,max,skillid;
nullpo_retr(0, bl);
- if(bl->type==BL_MOB)
- md=(struct mob_data *)bl;
- if(bl->type==BL_PC)
- sd=(struct map_session_data *)bl;
+ if (bl->type==BL_MOB) {
+ max = MAX_MOBSKILLUNITGROUP;
+ md = (struct mob_data *)bl;
+ } else if(bl->type==BL_PC) {
+ max = MAX_SKILLUNITGROUP;
+ sd = (struct map_session_data *)bl;
+ } else
+ return 0;
- for(i=0;i<MAX_MOBSKILLUNITGROUP;i++){
+ for (i=0;i<max;i++) {
if(sd){
skillid=sd->skillunit[i].skill_id;
if(skillid==SA_DELUGE||skillid==SA_VOLCANO||skillid==SA_VIOLENTGALE||skillid==SA_LANDPROTECTOR)
@@ -8190,43 +7912,43 @@ int skill_landprotector(struct block_list *bl, va_list ap )
nullpo_retr(0, bl);
nullpo_retr(0, ap);
- skillid=va_arg(ap,int);
- alive=va_arg(ap,int *);
- if((unit=(struct skill_unit *)bl) == NULL)
+ skillid = va_arg(ap,int);
+ alive = va_arg(ap,int *);
+
+ if ((unit = (struct skill_unit *)bl) == NULL)
return 0;
- if(skillid==SA_LANDPROTECTOR){
+ if (skillid == SA_LANDPROTECTOR)
skill_delunit(unit);
- }else{
- if(alive && unit->group->skill_id==SA_LANDPROTECTOR)
- (*alive)=0;
- }
+ else if (alive && unit->group && unit->group->skill_id == SA_LANDPROTECTOR)
+ (*alive) = 0;
+
return 0;
}
/*==========================================
* ƒCƒhƒDƒ“‚Ì—ÑŒç‚̉ñ•œ?—(foreachinarea)
*------------------------------------------
*/
-int skill_idun_heal(struct block_list *bl, va_list ap )
+int skill_idun_heal (struct block_list *bl, va_list ap)
{
struct skill_unit *unit;
struct skill_unit_group *sg;
int heal;
nullpo_retr(0, bl);
+ if (bl->type != BL_PC && bl->type != BL_MOB)
+ return 0;
+
nullpo_retr(0, ap);
nullpo_retr(0, unit = va_arg(ap,struct skill_unit *));
nullpo_retr(0, sg = unit->group);
-
- heal=30+sg->skill_lv*5+((sg->val1)>>16)*5+((sg->val1)&0xfff)/2;
-
- if(bl->type == BL_SKILL || bl->id == sg->src_id)
+ if (bl->id == sg->src_id)
return 0;
- if(bl->type == BL_PC || bl->type == BL_MOB){
- clif_skill_nodamage(&unit->bl,bl,AL_HEAL,heal,1);
- battle_heal(NULL,bl,heal,0,0);
- }
+ heal = 30 + sg->skill_lv * 5 + ((sg->val1) >> 16) * 5 + ((sg->val1) & 0xfff) / 2;
+ clif_skill_nodamage(&unit->bl, bl, AL_HEAL, heal, 1);
+ battle_heal(NULL, bl, heal, 0, 0);
+
return 0;
}
@@ -8234,18 +7956,19 @@ int skill_idun_heal(struct block_list *bl, va_list ap )
* Žw’è”Í??‚Åsrc‚É?‚µ‚Ä—L?‚ȃ^?ƒQƒbƒg‚Ìbl‚Ì?‚ð?‚¦‚é(foreachinarea)
*------------------------------------------
*/
-int skill_count_target(struct block_list *bl, va_list ap ){
+int skill_count_target (struct block_list *bl, va_list ap)
+{
struct block_list *src;
int *c;
nullpo_retr(0, bl);
nullpo_retr(0, ap);
- if((src = va_arg(ap,struct block_list *)) == NULL)
+ if ((src = va_arg(ap,struct block_list *)) == NULL)
return 0;
- if((c = va_arg(ap,int *)) == NULL)
+ if ((c = va_arg(ap,int *)) == NULL)
return 0;
- if(battle_check_target(src,bl,BCT_ENEMY) > 0)
+ if (battle_check_target(src,bl,BCT_ENEMY) > 0)
(*c)++;
return 0;
}
@@ -8253,7 +7976,7 @@ int skill_count_target(struct block_list *bl, va_list ap ){
* ƒgƒ‰ƒbƒv”Í??—(foreachinarea)
*------------------------------------------
*/
-int skill_trap_splash(struct block_list *bl, va_list ap )
+int skill_trap_splash (struct block_list *bl, va_list ap)
{
struct block_list *src;
int tick;
@@ -8285,6 +8008,7 @@ int skill_trap_splash(struct block_list *bl, va_list ap )
for(i=0;i<splash_count;i++){
skill_attack(BF_MISC,ss,src,bl,sg->skill_id,sg->skill_lv,tick,(sg->val2)?0x0500:0);
}
+ break;
case 0x97: /* ƒtƒŠ?ƒWƒ“ƒOƒgƒ‰ƒbƒv */
skill_attack(BF_WEAPON, ss,src,bl,sg->skill_id,sg->skill_lv,tick,(sg->val2)?0x0500:0);
break;
@@ -8295,1720 +8019,74 @@ int skill_trap_splash(struct block_list *bl, va_list ap )
return 0;
}
-/*----------------------------------------------------------------------------
- * ƒXƒe?ƒ^ƒXˆÙí
- *----------------------------------------------------------------------------
- */
-
-/*==========================================
- * ƒXƒe?ƒ^ƒXˆÙíƒ^ƒCƒ}?”Í??—
- *------------------------------------------
- */
-int skill_status_change_timer_sub(struct block_list *bl, va_list ap )
-{
- struct block_list *src;
- int type;
- unsigned int tick;
-
- nullpo_retr(0, bl);
- nullpo_retr(0, ap);
- nullpo_retr(0, src=va_arg(ap,struct block_list*));
- type=va_arg(ap,int);
- tick=va_arg(ap,unsigned int);
-
- if(bl->type!=BL_PC && bl->type!=BL_MOB)
- return 0;
-
- switch( type ){
- case SC_SIGHT: /* ƒTƒCƒg */
- case SC_CONCENTRATE:
- if( (*battle_get_option(bl))&6 ){
- skill_status_change_end( bl, SC_HIDING, -1);
- skill_status_change_end( bl, SC_CLOAKING, -1);
- }
- break;
- case SC_RUWACH: /* ƒ‹ƒAƒt */
- if( (*battle_get_option(bl))&6 ){
- skill_status_change_end( bl, SC_HIDING, -1);
- skill_status_change_end( bl, SC_CLOAKING, -1);
- if(battle_check_target( src,bl, BCT_ENEMY ) > 0) {
- struct status_change *sc_data = battle_get_sc_data(bl);
- skill_attack(BF_MAGIC,src,src,bl,AL_RUWACH,sc_data[type].val1,tick,0);
- }
- }
- break;
- }
- return 0;
-}
-
-/*==========================================
- * ƒXƒe?ƒ^ƒXˆÙíI—¹
- *------------------------------------------
- */
-int skill_status_change_end(struct block_list* bl, int type, int tid)
-{
- struct status_change* sc_data;
- int opt_flag=0, calc_flag = 0;
- short *sc_count, *option, *opt1, *opt2, *opt3;
-
- nullpo_retr(0, bl);
- if(bl->type!=BL_PC && bl->type!=BL_MOB) {
- if(battle_config.error_log)
- printf("skill_status_change_end: neither MOB nor PC !\n");
- return 0;
- }
- nullpo_retr(0, sc_data = battle_get_sc_data(bl));
- nullpo_retr(0, sc_count = battle_get_sc_count(bl));
- nullpo_retr(0, option = battle_get_option(bl));
- nullpo_retr(0, opt1 = battle_get_opt1(bl));
- nullpo_retr(0, opt2 = battle_get_opt2(bl));
- nullpo_retr(0, opt3 = battle_get_opt3(bl));
-
- if ((*sc_count) > 0 && sc_data[type].timer != -1 && (sc_data[type].timer == tid || tid == -1)) {
-
- if (tid == -1) // ƒ^ƒCƒ}‚©‚çŒÄ‚΂ê‚Ä‚¢‚È‚¢‚È‚çƒ^ƒCƒ}íœ‚ð‚·‚é
- delete_timer(sc_data[type].timer,skill_status_change_timer);
-
- /* ŠY?‚̈Ùí‚ð³í‚É?‚· */
- sc_data[type].timer=-1;
- (*sc_count)--;
-
- switch(type){ /* ˆÙí‚ÌŽí—Þ‚²‚Æ‚Ì?— */
- case SC_PROVOKE: /* ƒvƒƒ{ƒbƒN */
- case SC_ENDURE: // celest
- case SC_CONCENTRATE: /* W’†—ÍŒüã */
- case SC_BLESSING: /* ƒuƒŒƒbƒVƒ“ƒO */
- case SC_ANGELUS: /* ƒAƒ“ƒ[ƒ‹ƒX */
- case SC_INCREASEAGI: /* ‘¬“x㸠*/
- case SC_DECREASEAGI: /* ‘¬“xŒ¸­ */
- case SC_SIGNUMCRUCIS: /* ƒVƒOƒiƒ€ƒNƒ‹ƒVƒX */
- case SC_HIDING:
- case SC_TWOHANDQUICKEN: /* 2HQ */
- case SC_ADRENALINE: /* ƒAƒhƒŒƒiƒŠƒ“ƒ‰ƒbƒVƒ… */
- case SC_ENCPOISON: /* ƒGƒ“ƒ`ƒƒƒ“ƒgƒ|ƒCƒYƒ“ */
- case SC_IMPOSITIO: /* ƒCƒ“ƒ|ƒVƒeƒBƒIƒ}ƒkƒX */
- case SC_GLORIA: /* ƒOƒƒŠƒA */
- case SC_LOUD: /* ƒ‰ƒEƒhƒ{ƒCƒX */
- case SC_QUAGMIRE: /* ƒNƒ@ƒOƒ}ƒCƒA */
- case SC_PROVIDENCE: /* ƒvƒƒ”ƒBƒfƒ“ƒX */
- case SC_SPEARSQUICKEN: /* ƒXƒsƒAƒNƒCƒbƒPƒ“ */
- case SC_VOLCANO:
- case SC_DELUGE:
- case SC_VIOLENTGALE:
- case SC_ETERNALCHAOS: /* ƒGƒ^?ƒiƒ‹ƒJƒIƒX */
- case SC_DRUMBATTLE: /* ?‘¾ŒÛ‚Ì‹¿‚« */
- case SC_NIBELUNGEN: /* ƒj?ƒxƒ‹ƒ“ƒO‚ÌŽw—Ö */
- case SC_SIEGFRIED: /* •sŽ€g‚̃W?ƒNƒtƒŠ?ƒh */
- case SC_WHISTLE: /* Œû“J */
- case SC_ASSNCROS: /* —[—z‚̃AƒTƒVƒ“ƒNƒƒX */
- case SC_HUMMING: /* ƒnƒ~ƒ“ƒO */
- case SC_DONTFORGETME: /* Ž„‚ð–Y‚ê‚È‚¢‚Å */
- case SC_FORTUNE: /* K‰^‚̃LƒX */
- case SC_SERVICE4U: /* ƒT?ƒrƒXƒtƒH?ƒ†? */
- case SC_EXPLOSIONSPIRITS: // ”š—ô”g“®
- case SC_STEELBODY: // ‹à„
- case SC_DEFENDER:
- case SC_SPEEDPOTION0: /* ?‘¬ƒ|?ƒVƒ‡ƒ“ */
- case SC_SPEEDPOTION1:
- case SC_SPEEDPOTION2:
- case SC_APPLEIDUN: /* ƒCƒhƒDƒ“‚Ì—ÑŒç */
- case SC_RIDING:
- case SC_BLADESTOP_WAIT:
- case SC_AURABLADE: /* ƒI?ƒ‰ƒuƒŒ?ƒh */
- case SC_PARRYING: /* ƒpƒŠƒCƒ“ƒO */
- case SC_CONCENTRATION: /* ƒRƒ“ƒZƒ“ƒgƒŒ?ƒVƒ‡ƒ“ */
- case SC_TENSIONRELAX: /* ƒeƒ“ƒVƒ‡ƒ“ƒŠƒ‰ƒbƒNƒX */
- case SC_ASSUMPTIO: /* ƒAƒVƒƒƒ“ƒvƒeƒBƒI */
- case SC_WINDWALK: /* ƒEƒCƒ“ƒhƒEƒH?ƒN */
- case SC_TRUESIGHT: /* ƒgƒDƒ‹?ƒTƒCƒg */
- case SC_SPIDERWEB: /* ƒXƒpƒCƒ_?ƒEƒFƒbƒu */
- case SC_MAGICPOWER: /* –‚–@—Í?• */
- case SC_CHASEWALK:
- case SC_ATKPOT: /* attack potion [Valaris] */
- case SC_MATKPOT: /* magic attack potion [Valaris] */
- case SC_WEDDING: //Œ‹¥—p(Œ‹¥ˆßւɂȂÁ‚Ä?‚­‚Ì‚ª?‚¢‚Æ‚©)
- case SC_MELTDOWN: /* ƒƒ‹ƒgƒ_ƒEƒ“ */
- // Celest
- case SC_EDP:
- case SC_MARIONETTE:
- case SC_MARIONETTE2:
- case SC_SLOWDOWN:
- case SC_LEADERSHIP:
- case SC_GLORYWOUNDS:
- case SC_SOULCOLD:
- case SC_HAWKEYES:
- case SC_BATTLEORDERS:
- case SC_REGENERATION:
- calc_flag = 1;
- break;
- case SC_BERSERK: /* ƒo?ƒT?ƒN */
- calc_flag = 1;
- clif_status_change(bl,SC_INCREASEAGI,0); /* ƒAƒCƒRƒ“Á‹Ž */
- break;
- case SC_DEVOTION: /* ƒfƒBƒ{?ƒVƒ‡ƒ“ */
- {
- struct map_session_data *md = map_id2sd(sc_data[type].val1);
- sc_data[type].val1=sc_data[type].val2=0;
- skill_devotion(md,bl->id);
- calc_flag = 1;
- }
- break;
- case SC_BLADESTOP:
- {
- struct status_change *t_sc_data = battle_get_sc_data((struct block_list *)sc_data[type].val4);
- //•Еû‚ªØ‚ꂽ‚Ì‚Å‘ŠŽè‚Ì”’n?‘Ô‚ªØ‚ê‚ĂȂ¢‚̂Ȃç‰ðœ
- if(t_sc_data && t_sc_data[SC_BLADESTOP].timer!=-1)
- skill_status_change_end((struct block_list *)sc_data[type].val4,SC_BLADESTOP,-1);
-
- if(sc_data[type].val2==2)
- clif_bladestop((struct block_list *)sc_data[type].val3,(struct block_list *)sc_data[type].val4,0);
- }
- break;
- case SC_DANCING:
- {
- struct map_session_data *dsd;
- struct status_change *d_sc_data;
- if(sc_data[type].val4 && (dsd=map_id2sd(sc_data[type].val4))){
- d_sc_data = dsd->sc_data;
- //‡‘t‚Å‘ŠŽè‚ª‚¢‚éê‡‘ŠŽè‚Ìval4‚ð0‚É‚·‚é
- if(d_sc_data && d_sc_data[type].timer!=-1)
- d_sc_data[type].val4=0;
- }
- }
- calc_flag = 1;
- break;
- case SC_GRAFFITI:
- {
- struct skill_unit_group *sg=(struct skill_unit_group *)sc_data[type].val4; //val4‚ªƒOƒ‰ƒtƒBƒeƒB‚Ìgroup_id
- if(sg)
- skill_delunitgroup(sg);
- }
- break;
- case SC_NOCHAT: //ƒ`ƒƒƒbƒg‹ÖŽ~?‘Ô
- {
- struct map_session_data *sd=NULL;
- if(bl->type == BL_PC && (sd=(struct map_session_data *)bl)){
- if (sd->status.manner >= 0) // weeee ^^ [celest]
- sd->status.manner = 0;
- clif_updatestatus(sd,SP_MANNER);
- }
- }
- break;
- case SC_SPLASHER: /* ƒxƒiƒ€ƒXƒvƒ‰ƒbƒVƒƒ? */
- {
- struct block_list *src=map_id2bl(sc_data[type].val3);
- if(src && tid!=-1){
- //Ž©•ª‚Ƀ_ƒ?ƒW•Žü?3*3‚Ƀ_ƒ?ƒW
- skill_castend_damage_id(src, bl,sc_data[type].val2,sc_data[type].val1,gettick(),0 );
- }
- }
- break;
- case SC_SELFDESTRUCTION: /* Ž©”š */
- {
- //Ž©•ª‚̃_ƒ?ƒW‚Í0‚É‚µ‚Ä
- struct mob_data *md=NULL;
- if(bl->type == BL_MOB && (md=(struct mob_data*)bl))
- skill_castend_damage_id(bl, bl,sc_data[type].val2,sc_data[type].val1,gettick(),0 );
- }
- break;
- /* option1 */
- case SC_FREEZE:
- sc_data[type].val3 = 0;
- break;
-
- /* option2 */
- case SC_POISON: /* “Å */
- case SC_BLIND: /* ˆÃ? */
- case SC_CURSE:
- calc_flag = 1;
- break;
- }
-
- if(bl->type==BL_PC && type<SC_SENDMAX)
- clif_status_change(bl,type,0); /* ƒAƒCƒRƒ“Á‹Ž */
-
- switch(type){ /* ³í‚É?‚邯‚«‚Ȃɂ©?—‚ª•K—v */
- case SC_STONE:
- case SC_FREEZE:
- case SC_STAN:
- case SC_SLEEP:
- *opt1 = 0;
- opt_flag = 1;
- break;
-
- case SC_POISON:
- if (sc_data[SC_DPOISON].timer != -1) //
- break; // DPOISON—p‚̃IƒvƒVƒ‡ƒ“
- *opt2 &= ~1; // ‚ª?—p‚É—pˆÓ‚³‚ꂽꇂɂÍ
- opt_flag = 1; // ‚±‚±‚Í휂·‚é
- break; //
- case SC_CURSE:
- case SC_SILENCE:
- case SC_BLIND:
- *opt2 &= ~(1<<(type-SC_POISON));
- opt_flag = 1;
- break;
- case SC_DPOISON:
- if (sc_data[SC_POISON].timer != -1) // DPOISON—p‚̃IƒvƒVƒ‡ƒ“‚ª
- break; // —pˆÓ‚³‚ꂽ‚çíœ
- *opt2 &= ~1; // “Å?‘Ô‰ðœ
- opt_flag = 1;
- break;
- case SC_SIGNUMCRUCIS:
- *opt2 &= ~0x40;
- opt_flag = 1;
- break;
-
- case SC_HIDING:
- case SC_CLOAKING:
- *option &= ~((type == SC_HIDING) ? 2 : 4);
- calc_flag = 1; // orn
- opt_flag = 1 ;
- break;
-
- case SC_CHASEWALK:
- *option &= ~16388;
- opt_flag = 1 ;
- break;
-
- case SC_SIGHT:
- *option &= ~1;
- opt_flag = 1;
- break;
- case SC_WEDDING: //Œ‹¥—p(Œ‹¥ˆßւɂȂÁ‚Ä?‚­‚Ì‚ª?‚¢‚Æ‚©)
- *option &= ~4096;
- opt_flag = 1;
- break;
- case SC_RUWACH:
- *option &= ~8192;
- opt_flag = 1;
- break;
-
- //opt3
- case SC_TWOHANDQUICKEN: /* 2HQ */
- case SC_SPEARSQUICKEN: /* ƒXƒsƒAƒNƒCƒbƒPƒ“ */
- case SC_CONCENTRATION: /* ƒRƒ“ƒZƒ“ƒgƒŒ?ƒVƒ‡ƒ“ */
- *opt3 &= ~1;
- break;
- case SC_OVERTHRUST: /* ƒI?ƒo?ƒXƒ‰ƒXƒg */
- *opt3 &= ~2;
- break;
- case SC_ENERGYCOAT: /* ƒGƒiƒW?ƒR?ƒg */
- *opt3 &= ~4;
- break;
- case SC_EXPLOSIONSPIRITS: // ”š—ô”g“®
- *opt3 &= ~8;
- break;
- case SC_STEELBODY: // ‹à„
- *opt3 &= ~16;
- break;
- case SC_BLADESTOP: /* ”’nŽæ‚è */
- *opt3 &= ~32;
- break;
- case SC_BERSERK: /* ƒo?ƒT?ƒN */
- *opt3 &= ~128;
- break;
- case SC_MARIONETTE: /* ƒ}ƒŠƒIƒlƒbƒgƒRƒ“ƒgƒ?ƒ‹ */
- case SC_MARIONETTE2:
- *opt3 &= ~1024;
- break;
- case SC_ASSUMPTIO: /* ƒAƒXƒ€ƒvƒeƒBƒI */
- *opt3 &= ~2048;
- break;
- }
-
- if (night_flag == 1 && (*opt2 & STATE_BLIND) == 0 && bl->type == BL_PC && // by [Yor]
- !map[bl->m].flag.indoors && battle_config.night_darkness_level <= 0) { // [celest]
- *opt2 |= STATE_BLIND;
- opt_flag = 1;
- }
-
- if(opt_flag) /* option‚Ì?X‚ð?‚¦‚é */
- clif_changeoption(bl);
-
- if (bl->type == BL_PC && calc_flag)
- pc_calcstatus((struct map_session_data *)bl,0); /* ƒXƒe?ƒ^ƒXÄŒvŽZ */
- }
-
- return 0;
-}
-/*==========================================
- * ƒXƒe?ƒ^ƒXˆÙíI—¹ƒ^ƒCƒ}?
- *------------------------------------------
- */
-int skill_status_change_timer(int tid, unsigned int tick, int id, int data)
-{
- int type=data;
- struct block_list *bl;
- struct map_session_data *sd=NULL;
- struct status_change *sc_data;
- //short *sc_count; //Žg‚Á‚ĂȂ¢H
-
- if( (bl=map_id2bl(id)) == NULL )
- return 0; //ŠY?ID‚ª‚·‚Å‚ÉÁ–Å‚µ‚Ä‚¢‚邯‚¢‚¤‚̂͂¢‚©‚É‚à‚ ‚è‚»‚¤‚Ȃ̂ŃXƒ‹?‚µ‚Ă݂é
- nullpo_retr(0, sc_data=battle_get_sc_data(bl));
-
- if(bl->type==BL_PC)
- sd=(struct map_session_data *)bl;
-
- //sc_count=battle_get_sc_count(bl); //Žg‚Á‚ĂȂ¢H
-
- if(sc_data[type].timer != tid) {
- if(battle_config.error_log)
- printf("skill_status_change_timer %d != %d\n",tid,sc_data[type].timer);
- }
-
- switch(type){ /* “ÁŽê‚È?—‚ɂȂéê‡ */
- case SC_MAXIMIZEPOWER: /* ƒ}ƒLƒVƒ}ƒCƒYƒpƒ? */
- case SC_CLOAKING:
- if(sd){
- if( sd->status.sp > 0 ){ /* SPØ‚ê‚é‚܂Ŏ? */
- sd->status.sp--;
- clif_updatestatus(sd,SP_SP);
- sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
- sc_data[type].val2+tick, skill_status_change_timer, bl->id, data);
- return 0;
- }
- }
- break;
-
- case SC_CHASEWALK:
- if(sd){
- if( sd->status.sp > 19+sc_data[SC_CHASEWALK].val1*3){
- sd->status.sp-=(19+(sc_data[SC_CHASEWALK].val1*3)); // update sp cost [Celest]
- clif_updatestatus(sd,SP_SP);
- sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
- sc_data[type].val2+tick, skill_status_change_timer, bl->id, data);
- return 0;
- }
- }
- break;
-
- case SC_HIDING: /* ƒnƒCƒfƒBƒ“ƒO */
- if(sd){ /* SP‚ª‚ ‚Á‚ÄAŽžŠÔ§ŒÀ‚ÌŠÔ‚ÍŽ? */
- if( sd->status.sp > 0 && (--sc_data[type].val2)>0 ){
- if(sc_data[type].val2 % (sc_data[type].val1+3) ==0 ){
- sd->status.sp--;
- clif_updatestatus(sd,SP_SP);
- }
- sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
- 1000+tick, skill_status_change_timer,
- bl->id, data);
- return 0;
- }
- }
- break;
-
- case SC_SIGHT: /* ƒTƒCƒg */
- {
- const int range=7;
- map_foreachinarea( skill_status_change_timer_sub,
- bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,0,
- bl,type,tick);
-
- if( (--sc_data[type].val2)>0 ){
- sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
- 250+tick, skill_status_change_timer,
- bl->id, data);
- return 0;
- }
- }
- break;
- case SC_RUWACH: /* ƒ‹ƒAƒt */
- {
- const int range=5;
- map_foreachinarea( skill_status_change_timer_sub,
- bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,0,
- bl,type,tick);
-
- if( (--sc_data[type].val2)>0 ){
- sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
- 250+tick, skill_status_change_timer,
- bl->id, data);
- return 0;
- }
- }
- break;
-
- case SC_SIGNUMCRUCIS: /* ƒVƒOƒiƒ€ƒNƒ‹ƒVƒX */
- {
- int race = battle_get_race(bl);
- if(race == 6 || battle_check_undead(race,battle_get_elem_type(bl))) {
- sc_data[type].timer=add_timer(1000*600+tick,skill_status_change_timer, bl->id, data );
- return 0;
- }
- }
- break;
-
- case SC_PROVOKE: /* ƒvƒƒ{ƒbƒN/ƒI?ƒgƒo?ƒT?ƒN */
- if(sc_data[type].val2!=0){ /* ƒI?ƒgƒo?ƒT?ƒNi‚P•b‚²‚Æ‚ÉHPƒ`ƒFƒbƒNj */
- if(sd && sd->status.hp>sd->status.max_hp>>2) /* ’âŽ~ */
- break;
- sc_data[type].timer=add_timer( 1000+tick,skill_status_change_timer, bl->id, data );
- return 0;
- }
- break;
-
- case SC_WATERBALL: /* ƒEƒH?ƒ^?ƒ{?ƒ‹ */
- {
- struct block_list *target=map_id2bl(sc_data[type].val2);
- if(target==NULL || target->prev==NULL)
- break;
- skill_attack(BF_MAGIC,bl,bl,target,WZ_WATERBALL,sc_data[type].val1,tick,0);
- if((--sc_data[type].val3)>0) {
- sc_data[type].timer=add_timer( 150+tick,skill_status_change_timer, bl->id, data );
- return 0;
- }
- }
- break;
-
- case SC_ENDURE: /* ƒCƒ“ƒfƒ…ƒA */
- if(sd && sd->special_state.infinite_endure) {
- sc_data[type].timer=add_timer( 1000*60+tick,skill_status_change_timer, bl->id, data );
- //sc_data[type].val2=1;
- return 0;
- }
- break;
-
- case SC_DISSONANCE: /* •s‹¦˜a‰¹ */
- if( (--sc_data[type].val2)>0){
- struct skill_unit *unit=
- (struct skill_unit *)sc_data[type].val4;
- struct block_list *src;
-
- if(!unit || !unit->group)
- break;
- src=map_id2bl(unit->group->src_id);
- if(!src)
- break;
- skill_attack(BF_MISC,src,&unit->bl,bl,unit->group->skill_id,sc_data[type].val1,tick,0);
- sc_data[type].timer=add_timer(skill_get_time2(unit->group->skill_id,unit->group->skill_lv)+tick,
- skill_status_change_timer, bl->id, data );
- return 0;
- }
- break;
-
- case SC_LULLABY: /* ŽqŽç‰S */
- if( (--sc_data[type].val2)>0){
- struct skill_unit *unit=
- (struct skill_unit *)sc_data[type].val4;
- if(!unit || !unit->group || unit->group->src_id==bl->id)
- break;
- skill_additional_effect(bl,bl,unit->group->skill_id,sc_data[type].val1,BF_LONG|BF_SKILL|BF_MISC,tick);
- sc_data[type].timer=add_timer(skill_get_time(unit->group->skill_id,unit->group->skill_lv)/10+tick,
- skill_status_change_timer, bl->id, data );
- return 0;
- }
- break;
-
- case SC_STONE:
- if(sc_data[type].val2 != 0) {
- short *opt1 = battle_get_opt1(bl);
- sc_data[type].val2 = 0;
- sc_data[type].val4 = 0;
- battle_stopwalking(bl,1);
- if(opt1) {
- *opt1 = 1;
- clif_changeoption(bl);
- }
- sc_data[type].timer=add_timer(1000+tick,skill_status_change_timer, bl->id, data );
- return 0;
- }
- else if( (--sc_data[type].val3) > 0) {
- int hp = battle_get_max_hp(bl);
- if((++sc_data[type].val4)%5 == 0 && battle_get_hp(bl) > hp>>2) {
- hp = hp/100;
- if(hp < 1) hp = 1;
- if(bl->type == BL_PC)
- pc_heal((struct map_session_data *)bl,-hp,0);
- else if(bl->type == BL_MOB){
- struct mob_data *md;
- if((md=((struct mob_data *)bl)) == NULL)
- break;
- md->hp -= hp;
- }
- }
- sc_data[type].timer=add_timer(1000+tick,skill_status_change_timer, bl->id, data );
- return 0;
- }
- break;
- case SC_POISON:
- if(sc_data[SC_SLOWPOISON].timer == -1) {
- if( (--sc_data[type].val3) > 0) {
- int hp = battle_get_max_hp(bl);
- if(battle_get_hp(bl) > hp>>2) {
- if(bl->type == BL_PC) {
- hp = 3 + hp*3/200;
- pc_heal((struct map_session_data *)bl,-hp,0);
- }
- else if(bl->type == BL_MOB) {
- struct mob_data *md;
- if((md=((struct mob_data *)bl)) == NULL)
- break;
- hp = 3 + hp/200;
- md->hp -= hp;
- }
- }
- sc_data[type].timer=add_timer(1000+tick,skill_status_change_timer, bl->id, data );
- }
- }
- else
- sc_data[type].timer=add_timer(1000+tick,skill_status_change_timer, bl->id, data );
- break;
- case SC_DPOISON:
- if (sc_data[SC_SLOWPOISON].timer == -1 && (--sc_data[type].val3) > 0) {
- int hp = battle_get_max_hp(bl);
- if (battle_get_hp(bl) > hp>>2) {
- if(bl->type == BL_PC) {
- hp = 3 + hp/50;
- pc_heal((struct map_session_data *)bl, -hp, 0);
- } else if (bl->type == BL_MOB) {
- struct mob_data *md;
- if ((md=((struct mob_data *)bl)) == NULL)
- break;
- hp = 3 + hp/100;
- md->hp -= hp;
- }
- }
- }
- if (sc_data[type].val3 > 0)
- sc_data[type].timer=add_timer(1000+tick,skill_status_change_timer, bl->id, data );
- break;
-
- case SC_TENSIONRELAX: /* ƒeƒ“ƒVƒ‡ƒ“ƒŠƒ‰ƒbƒNƒX */
- if(sd){ /* SP‚ª‚ ‚Á‚ÄAHP‚ª?ƒ^ƒ“‚łȂ¯‚ê‚Î?? */
- if( sd->status.sp > 12 && sd->status.max_hp > sd->status.hp ){
-/* if(sc_data[type].val2 % (sc_data[type].val1+3) ==0 ){
- sd->status.sp -= 12;
- clif_updatestatus(sd,SP_SP);
- } */
- sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
- 10000+tick, skill_status_change_timer,
- bl->id, data);
- return 0;
- }
- if(sd->status.max_hp <= sd->status.hp)
- skill_status_change_end(&sd->bl,SC_TENSIONRELAX,-1);
- }
- break;
- case SC_HEADCRUSH: // temporary damage [celest]
-// case SC_BLEEDING:
- if((--sc_data[type].val3) > 0) {
- int hp = battle_get_max_hp(bl);
- if(bl->type == BL_PC) {
- hp = 3 + hp*3/200;
- pc_heal((struct map_session_data *)bl,-hp,0);
- }
- else if(bl->type == BL_MOB) {
- struct mob_data *md;
- if((md=((struct mob_data *)bl)) == NULL)
- break;
- hp = 3 + hp/200;
- md->hp -= hp;
- }
- sc_data[type].timer=add_timer(1000+tick,skill_status_change_timer, bl->id, data );
- }
- break;
-
- /* ŽžŠÔ؂ꖳ‚µHH */
- case SC_AETERNA:
- case SC_TRICKDEAD:
- case SC_RIDING:
- case SC_FALCON:
- case SC_WEIGHT50:
- case SC_WEIGHT90:
- case SC_MAGICPOWER: /* –‚–@—Í?• */
- case SC_REJECTSWORD: /* ƒŠƒWƒFƒNƒgƒ\?ƒh */
- case SC_MEMORIZE: /* ƒƒ‚ƒ‰ƒCƒY */
- case SC_BROKNWEAPON:
- case SC_BROKNARMOR:
- if(sc_data[type].timer==tid)
- sc_data[type].timer=add_timer( 1000*600+tick,skill_status_change_timer, bl->id, data );
- return 0;
-
- case SC_DANCING: //ƒ_ƒ“ƒXƒXƒLƒ‹‚ÌŽžŠÔSPÁ”ï
- {
- int s=0;
- if(sd){
- if(sd->status.sp > 0 && (--sc_data[type].val3)>0){
- switch(sc_data[type].val1){
- case BD_RICHMANKIM: /* ƒjƒˆƒ‹ƒh‚̉ƒ 3•b‚ÉSP1 */
- case BD_DRUMBATTLEFIELD: /* ?‘¾ŒÛ‚Ì‹¿‚« 3•b‚ÉSP1 */
- case BD_RINGNIBELUNGEN: /* ƒj?ƒxƒ‹ƒ“ƒO‚ÌŽw—Ö 3•b‚ÉSP1 */
- case BD_SIEGFRIED: /* •sŽ€g‚̃W?ƒNƒtƒŠ?ƒh 3•b‚ÉSP1 */
- case BA_DISSONANCE: /* •s‹¦˜a‰¹ 3•b‚ÅSP1 */
- case BA_ASSASSINCROSS: /* —[—z‚̃AƒTƒVƒ“ƒNƒƒX 3•b‚ÅSP1 */
- case DC_UGLYDANCE: /* Ž©•ªŸŽè‚ȃ_ƒ“ƒX 3•b‚ÅSP1 */
- s=3;
- break;
- case BD_LULLABY: /* ŽqŽç‰Ì 4•b‚ÉSP1 */
- case BD_ETERNALCHAOS: /* ‰i‰“‚̬“× 4•b‚ÉSP1 */
- case BD_ROKISWEIL: /* ƒƒL‚Ì‹©‚Ñ 4•b‚ÉSP1 */
- case DC_FORTUNEKISS: /* K‰^‚̃LƒX 4•b‚ÅSP1 */
- s=4;
- break;
- case BD_INTOABYSS: /* [•£‚Ì’†‚É 5•b‚ÉSP1 */
- case BA_WHISTLE: /* Œû“J 5•b‚ÅSP1 */
- case DC_HUMMING: /* ƒnƒ~ƒ“ƒO 5•b‚ÅSP1 */
- case BA_POEMBRAGI: /* ƒuƒ‰ƒM‚ÌŽ 5•b‚ÅSP1 */
- case DC_SERVICEFORYOU: /* ƒT?ƒrƒXƒtƒH?ƒ†? 5•b‚ÅSP1 */
- s=5;
- break;
- case BA_APPLEIDUN: /* ƒCƒhƒDƒ“‚Ì—ÑŒç 6•b‚ÅSP1 */
- s=6;
- break;
- case DC_DONTFORGETME: /* Ž„‚ð–Y‚ê‚È‚¢‚Åc 10•b‚ÅSP1 */
- case CG_MOONLIT: /* ŒŽ–¾‚è‚Ìò‚É—Ž‚¿‚é‰Ô‚Ñ‚ç 10•b‚ÅSP1H */
- s=10;
- break;
- }
- if(s && ((sc_data[type].val3 % s) == 0)){
- sd->status.sp--;
- clif_updatestatus(sd,SP_SP);
- }
- sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
- 1000+tick, skill_status_change_timer,
- bl->id, data);
- return 0;
- }
- }
- }
- break;
- case SC_BERSERK: /* ƒo?ƒT?ƒN */
- if(sd){ /* HP‚ª100ˆÈã‚È‚ç?? */
- if( (sd->status.hp - sd->status.max_hp*5/100) > 100 ){ // 5% every 10 seconds [DracoRPG]
- sd->status.hp -= sd->status.max_hp*5/100; // changed to max hp [celest]
- clif_updatestatus(sd,SP_HP);
- sc_data[type].timer = add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
- 10000+tick, skill_status_change_timer,
- bl->id, data);
- return 0;
- }
- }
- break;
- case SC_WEDDING: //Œ‹¥—p(Œ‹¥ˆßւɂȂÁ‚Ä?‚­‚Ì‚ª?‚¢‚Æ‚©)
- if(sd){
- time_t timer;
- if(time(&timer) < ((sc_data[type].val2) + 3600)){ //1ŽžŠÔ‚½‚Á‚Ä‚¢‚È‚¢‚Ì‚Å??
- sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
- 10000+tick, skill_status_change_timer,
- bl->id, data);
- return 0;
- }
- }
- break;
- case SC_NOCHAT: //ƒ`ƒƒƒbƒg‹ÖŽ~?‘Ô
- if(sd && battle_config.muting_players){
- time_t timer;
- if((++sd->status.manner) && time(&timer) < ((sc_data[type].val2) + 60*(0-sd->status.manner))){ //ŠJŽn‚©‚çstatus.manner•ª?‚Á‚ĂȂ¢‚Ì‚Å??
- clif_updatestatus(sd,SP_MANNER);
- sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è(60•b) */
- 60000+tick, skill_status_change_timer,
- bl->id, data);
- return 0;
- }
- }
- break;
- case SC_SELFDESTRUCTION: /* Ž©”š */
- if(--sc_data[type].val3>0){
- struct mob_data *md;
- if(bl->type==BL_MOB && (md=(struct mob_data *)bl) && md->speed > 250){
- md->speed -= 250;
- md->next_walktime=tick;
- }
- sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
- 1000+tick, skill_status_change_timer,
- bl->id, data);
- return 0;
- }
- break;
- case SC_LEADERSHIP:
- case SC_GLORYWOUNDS:
- case SC_SOULCOLD:
- case SC_HAWKEYES:
- if (sd) {
- sc_data[type].timer = add_timer(
- 1000+tick, skill_status_change_timer,
- bl->id, data);
- }
- break;
- }
-
-
-
- return skill_status_change_end( bl,type,tid );
-}
/*==========================================
* ƒXƒe?ƒ^ƒXˆÙíI—¹
*------------------------------------------
*/
-int skill_encchant_eremental_end(struct block_list *bl,int type)
+int skill_enchant_elemental_end (struct block_list *bl, int type)
{
struct status_change *sc_data;
nullpo_retr(0, bl);
- nullpo_retr(0, sc_data=battle_get_sc_data(bl));
-
- if( type!=SC_ENCPOISON && sc_data[SC_ENCPOISON].timer!=-1 ) /* ƒGƒ“ƒ`ƒƒƒ“ƒgƒ|ƒCƒYƒ“‰ðœ */
- skill_status_change_end(bl,SC_ENCPOISON,-1);
- if( type!=SC_ASPERSIO && sc_data[SC_ASPERSIO].timer!=-1 ) /* ƒAƒXƒyƒ‹ƒVƒI‰ðœ */
- skill_status_change_end(bl,SC_ASPERSIO,-1);
- if( type!=SC_FLAMELAUNCHER && sc_data[SC_FLAMELAUNCHER].timer!=-1 ) /* ƒtƒŒƒCƒ€ƒ‰ƒ“ƒ`ƒƒ‰ðœ */
- skill_status_change_end(bl,SC_FLAMELAUNCHER,-1);
- if( type!=SC_FROSTWEAPON && sc_data[SC_FROSTWEAPON].timer!=-1 ) /* ƒtƒƒXƒgƒEƒFƒ|ƒ“‰ðœ */
- skill_status_change_end(bl,SC_FROSTWEAPON,-1);
- if( type!=SC_LIGHTNINGLOADER && sc_data[SC_LIGHTNINGLOADER].timer!=-1 ) /* ƒ‰ƒCƒgƒjƒ“ƒOƒ?ƒ_?‰ðœ */
- skill_status_change_end(bl,SC_LIGHTNINGLOADER,-1);
- if( type!=SC_SEISMICWEAPON && sc_data[SC_SEISMICWEAPON].timer!=-1 ) /* ƒTƒCƒXƒ~ƒbƒNƒEƒFƒ|ƒ“‰ðœ */
- skill_status_change_end(bl,SC_SEISMICWEAPON,-1);
+ nullpo_retr(0, sc_data = status_get_sc_data(bl));
+
+ if (type != SC_ENCPOISON && sc_data[SC_ENCPOISON].timer != -1) /* ƒGƒ“ƒ`ƒƒƒ“ƒgƒ|ƒCƒYƒ“‰ðœ */
+ status_change_end(bl, SC_ENCPOISON, -1);
+ if (type != SC_ASPERSIO && sc_data[SC_ASPERSIO].timer != -1) /* ƒAƒXƒyƒ‹ƒVƒI‰ðœ */
+ status_change_end(bl, SC_ASPERSIO, -1);
+ if (type != SC_FLAMELAUNCHER && sc_data[SC_FLAMELAUNCHER].timer != -1) /* ƒtƒŒƒCƒ€ƒ‰ƒ“ƒ`ƒƒ‰ðœ */
+ status_change_end(bl, SC_FLAMELAUNCHER, -1);
+ if (type != SC_FROSTWEAPON && sc_data[SC_FROSTWEAPON].timer != -1) /* ƒtƒƒXƒgƒEƒFƒ|ƒ“‰ðœ */
+ status_change_end(bl, SC_FROSTWEAPON, -1);
+ if (type != SC_LIGHTNINGLOADER && sc_data[SC_LIGHTNINGLOADER].timer != -1) /* ƒ‰ƒCƒgƒjƒ“ƒOƒ?ƒ_?‰ðœ */
+ status_change_end(bl, SC_LIGHTNINGLOADER, -1);
+ if (type != SC_SEISMICWEAPON && sc_data[SC_SEISMICWEAPON].timer != -1) /* ƒTƒCƒXƒ~ƒbƒNƒEƒFƒ|ƒ“‰ðœ */
+ status_change_end(bl, SC_SEISMICWEAPON, -1);
return 0;
}
-/*==========================================
- * ƒXƒe?ƒ^ƒXˆÙíŠJŽn
- *------------------------------------------
- */
-int skill_status_change_start(struct block_list *bl, int type, int val1, int val2, int val3, int val4, int tick, int flag)
+
+/* ƒNƒ?ƒLƒ“ƒO?¸iŽü‚è‚Ɉړ®•s‰Â”\’n?‚ª‚ ‚é‚©j */
+int skill_check_cloaking(struct block_list *bl)
{
struct map_session_data *sd = NULL;
- struct status_change* sc_data;
- short *sc_count, *option, *opt1, *opt2, *opt3;
- int opt_flag = 0, calc_flag = 0,updateflag = 0, save_flag = 0, race, mode, elem, undead_flag;
- int scdef=0;
-
- nullpo_retr(0, bl);
- if(bl->type == BL_SKILL)
- return 0;
- nullpo_retr(0, sc_data=battle_get_sc_data(bl));
- nullpo_retr(0, sc_count=battle_get_sc_count(bl));
- nullpo_retr(0, option=battle_get_option(bl));
- nullpo_retr(0, opt1=battle_get_opt1(bl));
- nullpo_retr(0, opt2=battle_get_opt2(bl));
- nullpo_retr(0, opt3=battle_get_opt3(bl));
-
-
- race=battle_get_race(bl);
- mode=battle_get_mode(bl);
- elem=battle_get_elem_type(bl);
- undead_flag=battle_check_undead(race,elem);
-
- if(type == SC_AETERNA && (sc_data[SC_STONE].timer != -1 || sc_data[SC_FREEZE].timer != -1) )
- return 0;
-
- switch(type){
- case SC_STONE:
- case SC_FREEZE:
- scdef=3+battle_get_mdef(bl)+battle_get_luk(bl)/3;
- break;
- case SC_STAN:
- case SC_SILENCE:
- case SC_POISON:
- case SC_DPOISON:
- scdef=3+battle_get_vit(bl)+battle_get_luk(bl)/3;
- break;
- case SC_SLEEP:
- case SC_BLIND:
- scdef=3+battle_get_int(bl)+battle_get_luk(bl)/3;
- break;
- case SC_CURSE:
- scdef=3+battle_get_luk(bl);
- break;
-
-// case SC_CONFUSION:
- default:
- scdef=0;
- }
- if(scdef>=100)
- return 0;
- if(bl->type==BL_PC){
- sd=(struct map_session_data *)bl;
- if( sd && type == SC_ADRENALINE && !(skill_get_weapontype(BS_ADRENALINE)&(1<<sd->status.weapon)))
- return 0;
-
- if(SC_STONE<=type && type<=SC_BLIND){ /* ƒJ?ƒh‚É‚æ‚é‘Ï« */
- if( sd && sd->reseff[type-SC_STONE] > 0 && rand()%10000<sd->reseff[type-SC_STONE]){
- if(battle_config.battle_log)
- printf("PC %d skill_sc_start: card‚É‚æ‚éˆÙí‘Ï«?“®\n",sd->bl.id);
- return 0;
- }
- }
- }
- else if(bl->type == BL_MOB) {
- }
- else {
- if(battle_config.error_log)
- printf("skill_status_change_start: neither MOB nor PC !\n");
- return 0;
- }
-
- if(type==SC_FREEZE && undead_flag && !(flag&1))
- return 0;
-
- if((type == SC_ADRENALINE || type == SC_WEAPONPERFECTION || type == SC_OVERTHRUST) &&
- sc_data[type].timer != -1 && sc_data[type].val2 && !val2)
- return 0;
-
- if(mode & 0x20 && (type==SC_STONE || type==SC_FREEZE ||
- type==SC_STAN || type==SC_SLEEP || type==SC_SILENCE || type==SC_QUAGMIRE || type == SC_DECREASEAGI || type == SC_SIGNUMCRUCIS || type == SC_PROVOKE ||
- (type == SC_BLESSING && (undead_flag || race == 6))) && !(flag&1)){
- /* ƒ{ƒX‚É‚Í?‚©‚È‚¢(‚½‚¾‚µƒJ?ƒh‚É‚æ‚é?‰Ê‚Í“K—p‚³‚ê‚é) */
- return 0;
- }
- if(type==SC_FREEZE || type==SC_STAN || type==SC_SLEEP)
- battle_stopwalking(bl,1);
+ static int dx[] = { 0, 1, 0, -1, -1, 1, 1, -1}; //optimized by Lupus
+ static int dy[] = {-1, 0, 1, 0, -1, -1, 1, 1};
+ int end = 1,i;
- if(sc_data[type].timer != -1){ /* ‚·‚łɓ¯‚¶ˆÙí‚ɂȂÁ‚Ä‚¢‚éꇃ^ƒCƒ}‰ðœ */
- if(sc_data[type].val1 > val1 && type != SC_COMBO && type != SC_DANCING && type != SC_DEVOTION &&
- type != SC_SPEEDPOTION0 && type != SC_SPEEDPOTION1 && type != SC_SPEEDPOTION2
- && type != SC_ATKPOT && type != SC_MATKPOT) // added atk and matk potions [Valaris]
- return 0;
- if(type >=SC_STAN && type <= SC_BLIND)
- return 0;/* ?‚¬‘«‚µ‚ª‚Å‚«‚È‚¢?‘ÔˆÙí‚Å‚ ‚鎞‚Í?‘ÔˆÙí‚ðs‚í‚È‚¢ */
- if(type == SC_GRAFFITI){ //ˆÙí’†‚É‚à‚¤ˆê“x?‘ÔˆÙí‚ɂȂÁ‚½Žž‚ɉ𜂵‚Ä‚©‚çÄ“x‚©‚©‚é
- skill_status_change_end(bl,type,-1);
- } else {
- (*sc_count)--;
- delete_timer(sc_data[type].timer, skill_status_change_timer);
- sc_data[type].timer = -1;
- }
- }
-
- switch(type){ /* ˆÙí‚ÌŽí—Þ‚²‚Æ‚Ì?— */
- case SC_PROVOKE: /* ƒvƒƒ{ƒbƒN */
- calc_flag = 1;
- if(tick <= 0) tick = 1000; /* (ƒI?ƒgƒo?ƒT?ƒN) */
- break;
- case SC_ENDURE: /* ƒCƒ“ƒfƒ…ƒA */
- if(tick <= 0) tick = 1000 * 60;
- calc_flag = 1; // for updating mdef
- val2 = 7; // [Celest]
- break;
- case SC_CONCENTRATE: /* W’†—ÍŒüã */
- calc_flag = 1;
- break;
- case SC_BLESSING: /* ƒuƒŒƒbƒVƒ“ƒO */
- {
- if(bl->type == BL_PC || (!undead_flag && race != 6)) {
- if(sc_data[SC_CURSE].timer!=-1 )
- skill_status_change_end(bl,SC_CURSE,-1);
- if(sc_data[SC_STONE].timer!=-1 && sc_data[SC_STONE].val2 == 0)
- skill_status_change_end(bl,SC_STONE,-1);
- }
- calc_flag = 1;
- }
- break;
- case SC_ANGELUS: /* ƒAƒ“ƒ[ƒ‹ƒX */
- calc_flag = 1;
- break;
- case SC_INCREASEAGI: /* ‘¬“x㸠*/
- calc_flag = 1;
- if(sc_data[SC_DECREASEAGI].timer!=-1 )
- skill_status_change_end(bl,SC_DECREASEAGI,-1);
- if(sc_data[SC_WINDWALK].timer!=-1 ) /* ƒEƒCƒ“ƒhƒEƒH?ƒN */
- skill_status_change_end(bl,SC_WINDWALK,-1);
- break;
- case SC_DECREASEAGI: /* ‘¬“xŒ¸­ */
- if (bl->type == BL_PC) // Celest
- tick>>=1;
- calc_flag = 1;
- if(sc_data[SC_INCREASEAGI].timer!=-1 )
- skill_status_change_end(bl,SC_INCREASEAGI,-1);
- if(sc_data[SC_ADRENALINE].timer!=-1 )
- skill_status_change_end(bl,SC_ADRENALINE,-1);
- if(sc_data[SC_SPEARSQUICKEN].timer!=-1 )
- skill_status_change_end(bl,SC_SPEARSQUICKEN,-1);
- if(sc_data[SC_TWOHANDQUICKEN].timer!=-1 )
- skill_status_change_end(bl,SC_TWOHANDQUICKEN,-1);
- break;
- case SC_SIGNUMCRUCIS: /* ƒVƒOƒiƒ€ƒNƒ‹ƒVƒX */
- calc_flag = 1;
-// val2 = 14 + val1;
- val2 = 10 + val1*2;
- tick = 600*1000;
- clif_emotion(bl,4);
- break;
- case SC_SLOWPOISON:
- if (sc_data[SC_POISON].timer == -1 && sc_data[SC_DPOISON].timer == -1)
- return 0;
- break;
- case SC_TWOHANDQUICKEN: /* 2HQ */
- if(sc_data[SC_DECREASEAGI].timer!=-1)
- return 0;
- *opt3 |= 1;
- calc_flag = 1;
- break;
- case SC_ADRENALINE: /* ƒAƒhƒŒƒiƒŠƒ“ƒ‰ƒbƒVƒ… */
- if(sc_data[SC_DECREASEAGI].timer!=-1)
- return 0;
- calc_flag = 1;
- break;
- case SC_WEAPONPERFECTION: /* ƒEƒFƒ|ƒ“ƒp?ƒtƒFƒNƒVƒ‡ƒ“ */
- if(battle_config.party_skill_penaly && !val2) tick /= 5;
- break;
- case SC_OVERTHRUST: /* ƒI?ƒo?ƒXƒ‰ƒXƒg */
- *opt3 |= 2;
- if(battle_config.party_skill_penaly && !val2) tick /= 10;
- break;
- case SC_MAXIMIZEPOWER: /* ƒ}ƒLƒVƒ}ƒCƒYƒpƒ?(SP‚ª1Œ¸‚鎞ŠÔ,val2‚É‚à) */
- if(bl->type == BL_PC)
- val2 = tick;
- else
- tick = 5000*val1;
- break;
- case SC_ENCPOISON: /* ƒGƒ“ƒ`ƒƒƒ“ƒgƒ|ƒCƒYƒ“ */
- calc_flag = 1;
- val2=(((val1 - 1) / 2) + 3)*100; /* “Å•t?Šm—¦ */
- skill_encchant_eremental_end(bl,SC_ENCPOISON);
- break;
- case SC_EDP: // [Celest]
- val2 = val1 + 2; /* –Ò“Å•t?Šm—¦(%) */
- calc_flag = 1;
- break;
- case SC_POISONREACT: /* ƒ|ƒCƒYƒ“ƒŠƒAƒNƒg */
- val2=val1/2 + val1%2; // [Celest]
- break;
- case SC_IMPOSITIO: /* ƒCƒ“ƒ|ƒVƒeƒBƒIƒ}ƒkƒX */
- calc_flag = 1;
- break;
- case SC_ASPERSIO: /* ƒAƒXƒyƒ‹ƒVƒI */
- skill_encchant_eremental_end(bl,SC_ASPERSIO);
- break;
- case SC_SUFFRAGIUM: /* ƒTƒtƒ‰ƒMƒ€ */
- case SC_BENEDICTIO: /* ¹? */
- case SC_MAGNIFICAT: /* ƒ}ƒOƒjƒtƒBƒJ?ƒg */
- case SC_AETERNA: /* ƒG?ƒeƒ‹ƒi */
- break;
- case SC_ENERGYCOAT: /* ƒGƒiƒW?ƒR?ƒg */
- *opt3 |= 4;
- break;
- case SC_MAGICROD:
- val2 = val1*20;
- break;
- case SC_KYRIE: /* ƒLƒŠƒGƒGƒŒƒCƒ\ƒ“ */
- val2 = battle_get_max_hp(bl) * (val1 * 2 + 10) / 100;/* ‘Ï‹v“x */
- val3 = (val1 / 2 + 5); /* ‰ñ? */
-// -- moonsoul (added to undo assumptio status if target has it)
- if(sc_data[SC_ASSUMPTIO].timer!=-1 )
- skill_status_change_end(bl,SC_ASSUMPTIO,-1);
- break;
- case SC_MINDBREAKER:
- calc_flag = 1;
- if(tick <= 0) tick = 1000; /* (ƒI?ƒgƒo?ƒT?ƒN) */
- case SC_GLORIA: /* ƒOƒƒŠƒA */
- calc_flag = 1;
- break;
- case SC_LOUD: /* ƒ‰ƒEƒhƒ{ƒCƒX */
- calc_flag = 1;
- break;
- case SC_TRICKDEAD: /* Ž€‚ñ‚¾‚Ó‚è */
- break;
- case SC_QUAGMIRE: /* ƒNƒ@ƒOƒ}ƒCƒA */
- calc_flag = 1;
- if(sc_data[SC_CONCENTRATE].timer!=-1 ) /* W’†—ÍŒüã‰ðœ */
- skill_status_change_end(bl,SC_CONCENTRATE,-1);
- if(sc_data[SC_INCREASEAGI].timer!=-1 ) /* ‘¬“x㸉ðœ */
- skill_status_change_end(bl,SC_INCREASEAGI,-1);
- if(sc_data[SC_TWOHANDQUICKEN].timer!=-1 )
- skill_status_change_end(bl,SC_TWOHANDQUICKEN,-1);
- if(sc_data[SC_SPEARSQUICKEN].timer!=-1 )
- skill_status_change_end(bl,SC_SPEARSQUICKEN,-1);
- if(sc_data[SC_ADRENALINE].timer!=-1 )
- skill_status_change_end(bl,SC_ADRENALINE,-1);
- if(sc_data[SC_LOUD].timer!=-1 )
- skill_status_change_end(bl,SC_LOUD,-1);
- if(sc_data[SC_TRUESIGHT].timer!=-1 ) /* ƒgƒDƒ‹?ƒTƒCƒg */
- skill_status_change_end(bl,SC_TRUESIGHT,-1);
- if(sc_data[SC_WINDWALK].timer!=-1 ) /* ƒEƒCƒ“ƒhƒEƒH?ƒN */
- skill_status_change_end(bl,SC_WINDWALK,-1);
- if(sc_data[SC_CARTBOOST].timer!=-1 ) /* ƒJ?ƒgƒu?ƒXƒg */
- skill_status_change_end(bl,SC_CARTBOOST,-1);
- break;
- case SC_FLAMELAUNCHER: /* ƒtƒŒ?ƒ€ƒ‰ƒ“ƒ`ƒƒ? */
- skill_encchant_eremental_end(bl,SC_FLAMELAUNCHER);
- break;
- case SC_FROSTWEAPON: /* ƒtƒƒXƒgƒEƒFƒ|ƒ“ */
- skill_encchant_eremental_end(bl,SC_FROSTWEAPON);
- break;
- case SC_LIGHTNINGLOADER: /* ƒ‰ƒCƒgƒjƒ“ƒOƒ?ƒ_? */
- skill_encchant_eremental_end(bl,SC_LIGHTNINGLOADER);
- break;
- case SC_SEISMICWEAPON: /* ƒTƒCƒYƒ~ƒbƒNƒEƒFƒ|ƒ“ */
- skill_encchant_eremental_end(bl,SC_SEISMICWEAPON);
- break;
- case SC_DEVOTION: /* ƒfƒBƒ{?ƒVƒ‡ƒ“ */
- calc_flag = 1;
- break;
- case SC_PROVIDENCE: /* ƒvƒƒ”ƒBƒfƒ“ƒX */
- calc_flag = 1;
- val2=val1*5;
- break;
- case SC_REFLECTSHIELD:
- val2=10+val1*3;
- break;
- case SC_STRIPWEAPON:
- case SC_STRIPSHIELD:
- case SC_STRIPARMOR:
- case SC_STRIPHELM:
- case SC_CP_WEAPON:
- case SC_CP_SHIELD:
- case SC_CP_ARMOR:
- case SC_CP_HELM:
- break;
-
- case SC_AUTOSPELL: /* ƒI?ƒgƒXƒyƒ‹ */
- val4 = 5 + val1*2;
- break;
-
- case SC_VOLCANO:
- calc_flag = 1;
- val3 = val1*10;
- val4 = val1>=5?20: (val1==4?19: (val1==3?17: ( val1==2?14:10 ) ) );
- break;
- case SC_DELUGE:
- calc_flag = 1;
- val3 = val1>=5?15: (val1==4?14: (val1==3?12: ( val1==2?9:5 ) ) );
- val4 = val1>=5?20: (val1==4?19: (val1==3?17: ( val1==2?14:10 ) ) );
- break;
- case SC_VIOLENTGALE:
- calc_flag = 1;
- val3 = val1*3;
- val4 = val1>=5?20: (val1==4?19: (val1==3?17: ( val1==2?14:10 ) ) );
- break;
-
- case SC_SPEARSQUICKEN: /* ƒXƒsƒAƒNƒCƒbƒPƒ“ */
- calc_flag = 1;
- val2 = 20+val1;
- *opt3 |= 1;
- break;
- case SC_COMBO:
- break;
- case SC_BLADESTOP_WAIT: /* ”’nŽæ‚è(‘Ò‚¿) */
- break;
- case SC_BLADESTOP: /* ”’nŽæ‚è */
- if(val2==2) clif_bladestop((struct block_list *)val3,(struct block_list *)val4,1);
- *opt3 |= 32;
- break;
-
- case SC_LULLABY: /* ŽqŽç‰S */
- val2 = 11;
- break;
- case SC_RICHMANKIM:
- break;
- case SC_ETERNALCHAOS: /* ƒGƒ^?ƒiƒ‹ƒJƒIƒX */
- calc_flag = 1;
- break;
- case SC_DRUMBATTLE: /* ?‘¾ŒÛ‚Ì‹¿‚« */
- calc_flag = 1;
- val2 = (val1+1)*25;
- val3 = (val1+1)*2;
- break;
- case SC_NIBELUNGEN: /* ƒj?ƒxƒ‹ƒ“ƒO‚ÌŽw—Ö */
- calc_flag = 1;
- val2 = (val1+2)*50;
- val3 = (val1+2)*25;
- break;
- case SC_ROKISWEIL: /* ƒƒL‚Ì‹©‚Ñ */
- break;
- case SC_INTOABYSS: /* [•£‚Ì’†‚É */
- break;
- case SC_SIEGFRIED: /* •sŽ€g‚̃W?ƒNƒtƒŠ?ƒh */
- calc_flag = 1;
- val2 = 40 + val1*5;
- val3 = val1*10;
- break;
- case SC_DISSONANCE: /* •s‹¦˜a‰¹ */
- val2 = 10;
- break;
- case SC_WHISTLE: /* Œû“J */
- calc_flag = 1;
- break;
- case SC_ASSNCROS: /* —[—z‚̃AƒTƒVƒ“ƒNƒƒX */
- calc_flag = 1;
- break;
- case SC_POEMBRAGI: /* ƒuƒ‰ƒM‚ÌŽ */
- break;
- case SC_APPLEIDUN: /* ƒCƒhƒDƒ“‚Ì—ÑŒç */
- calc_flag = 1;
- break;
- case SC_UGLYDANCE: /* Ž©•ªŸŽè‚ȃ_ƒ“ƒX */
- val2 = 10;
- break;
- case SC_HUMMING: /* ƒnƒ~ƒ“ƒO */
- calc_flag = 1;
- break;
- case SC_DONTFORGETME: /* Ž„‚ð–Y‚ê‚È‚¢‚Å */
- calc_flag = 1;
- if(sc_data[SC_INCREASEAGI].timer!=-1 ) /* ‘¬“x㸉ðœ */
- skill_status_change_end(bl,SC_INCREASEAGI,-1);
- if(sc_data[SC_TWOHANDQUICKEN].timer!=-1 )
- skill_status_change_end(bl,SC_TWOHANDQUICKEN,-1);
- if(sc_data[SC_SPEARSQUICKEN].timer!=-1 )
- skill_status_change_end(bl,SC_SPEARSQUICKEN,-1);
- if(sc_data[SC_ADRENALINE].timer!=-1 )
- skill_status_change_end(bl,SC_ADRENALINE,-1);
- if(sc_data[SC_ASSNCROS].timer!=-1 )
- skill_status_change_end(bl,SC_ASSNCROS,-1);
- if(sc_data[SC_TRUESIGHT].timer!=-1 ) /* ƒgƒDƒ‹?ƒTƒCƒg */
- skill_status_change_end(bl,SC_TRUESIGHT,-1);
- if(sc_data[SC_WINDWALK].timer!=-1 ) /* ƒEƒCƒ“ƒhƒEƒH?ƒN */
- skill_status_change_end(bl,SC_WINDWALK,-1);
- if(sc_data[SC_CARTBOOST].timer!=-1 ) /* ƒJ?ƒgƒu?ƒXƒg */
- skill_status_change_end(bl,SC_CARTBOOST,-1);
- break;
- case SC_FORTUNE: /* K‰^‚̃LƒX */
- calc_flag = 1;
- break;
- case SC_SERVICE4U: /* ƒT?ƒrƒXƒtƒH?ƒ†? */
- calc_flag = 1;
- break;
- case SC_DANCING: /* ƒ_ƒ“ƒX/‰‰‘t’† */
- calc_flag = 1;
- val3= tick / 1000;
- tick = 1000;
- break;
-
- case SC_EXPLOSIONSPIRITS: // ”š—ô”g“®
- calc_flag = 1;
- val2 = 75 + 25*val1;
- *opt3 |= 8;
- break;
- case SC_STEELBODY: // ‹à„
- calc_flag = 1;
- *opt3 |= 16;
- break;
- case SC_EXTREMITYFIST: /* ˆ¢C—…”e™€Œ */
- break;
- case SC_AUTOCOUNTER:
- val3 = val4 = 0;
- break;
-
- case SC_SPEEDPOTION0: /* ?‘¬ƒ|?ƒVƒ‡ƒ“ */
- case SC_SPEEDPOTION1:
- case SC_SPEEDPOTION2:
- calc_flag = 1;
- tick = 1000 * tick;
- val2 = 5*(2+type-SC_SPEEDPOTION0);
- break;
-
- /* atk & matk potions [Valaris] */
- case SC_ATKPOT:
- case SC_MATKPOT:
- calc_flag = 1;
- tick = 1000 * tick;
- break;
- case SC_WEDDING: //Œ‹¥—p(Œ‹¥ˆßւɂȂÁ‚Ä?‚­‚Ì‚ª?‚¢‚Æ‚©)
- {
- time_t timer;
-
- calc_flag = 1;
- tick = 10000;
- if(!val2)
- val2 = time(&timer);
- }
- break;
- case SC_NOCHAT: //ƒ`ƒƒƒbƒg‹ÖŽ~?‘Ô
- {
- time_t timer;
-
- if(!battle_config.muting_players)
- break;
-
- tick = 60000;
- if(!val2)
- val2 = time(&timer);
- updateflag = SP_MANNER;
- save_flag = 1; // celest
- }
- break;
- case SC_SELFDESTRUCTION: //Ž©”š
- clif_skillcasting(bl,bl->id, bl->id,0,0,331,skill_get_time(val2,val1));
- val3 = tick / 1000;
- tick = 1000;
- break;
-
- /* option1 */
- case SC_STONE: /* Ή» */
- if(!(flag&2)) {
- int sc_def = battle_get_mdef(bl)*200;
- tick = tick - sc_def;
- }
- val3 = tick/1000;
- if(val3 < 1) val3 = 1;
- tick = 5000;
- val2 = 1;
- break;
- case SC_SLEEP: /* ‡–° */
- if(!(flag&2)) {
-// int sc_def = 100 - (battle_get_int(bl) + battle_get_luk(bl)/3);
-// tick = tick * sc_def / 100;
-// if(tick < 1000) tick = 1000;
- tick = 30000;//‡–°‚̓Xƒe?ƒ^ƒX‘Ï«‚É?‚í‚炸30•b
- }
- break;
- case SC_FREEZE: /* “€Œ‹ */
- if(!(flag&2)) {
- int sc_def = 100 - battle_get_mdef(bl);
- tick = tick * sc_def / 100;
- }
- break;
- case SC_STAN: /* ƒXƒ^ƒ“ival2‚Ƀ~ƒŠ•bƒZƒbƒgj */
- if(!(flag&2)) {
- int sc_def = 100 - (battle_get_vit(bl) + battle_get_luk(bl)/3);
- tick = tick * sc_def / 100;
- }
- break;
-
- /* option2 */
- case SC_POISON: /* “Å */
- case SC_DPOISON: /* –Ò“Å */
- calc_flag = 1;
- if(!(flag&2)) {
- int sc_def = 100 - (battle_get_vit(bl) + battle_get_luk(bl)/5);
- tick = tick * sc_def / 100;
- }
- val3 = tick/1000;
- if(val3 < 1) val3 = 1;
- tick = 1000;
- break;
- case SC_SILENCE: /* ’¾?iƒŒƒbƒNƒXƒfƒr?ƒij */
- if(!(flag&2)) {
- int sc_def = 100 - battle_get_vit(bl);
- tick = tick * sc_def / 100;
- }
- break;
- case SC_BLIND: /* ˆÃ? */
- calc_flag = 1;
- if(!(flag&2)) {
- int sc_def = battle_get_lv(bl)/10 + battle_get_int(bl)/15;
- tick = 30000 - sc_def;
- }
- break;
- case SC_CURSE:
- calc_flag = 1;
- if(!(flag&2)) {
- int sc_def = 100 - battle_get_vit(bl);
- tick = tick * sc_def / 100;
- }
- break;
-
- /* option */
- case SC_HIDING: /* ƒnƒCƒfƒBƒ“ƒO */
- calc_flag = 1;
- if(bl->type == BL_PC) {
- val2 = tick / 1000; /* Ž?ŽžŠÔ */
- tick = 1000;
- }
- break;
- case SC_CHASEWALK:
- case SC_CLOAKING: /* ƒNƒ?ƒLƒ“ƒO */
- if(bl->type == BL_PC) {
- calc_flag = 1; // [Celest]
- val2 = tick;
- val3 = type==SC_CLOAKING ? 130-val1*3 : 135-val1*5;
- }
- else
- tick = 5000*val1;
- break;
- case SC_SIGHT: /* ƒTƒCƒg/ƒ‹ƒAƒt */
- case SC_RUWACH:
- val2 = tick/250;
- tick = 10;
- break;
-
- /* ƒZ?ƒtƒeƒBƒEƒH?ƒ‹Aƒjƒ…?ƒ} */
- case SC_SAFETYWALL: case SC_PNEUMA:
- tick=((struct skill_unit *)val2)->group->limit;
- break;
-
- /* ƒAƒ“ƒNƒ‹ */
- case SC_ANKLE:
- break;
-
- /* ƒEƒH?ƒ^?ƒ{?ƒ‹ */
- case SC_WATERBALL:
- tick=150;
- if(val1>5) //ƒŒƒxƒ‹‚ª5ˆÈã‚ÌꇂÍ25?‚ɧŒÀ(1?–Ú‚Í‚·‚łɑłÁ‚Ä‚é‚Ì‚Å-1)
- val3=5*5-1;
- else
- val3= (val1|1)*(val1|1)-1;
- break;
-
- /* ƒXƒLƒ‹‚¶‚á‚È‚¢/ŽžŠÔ‚É?ŒW‚µ‚È‚¢ */
- case SC_RIDING:
- calc_flag = 1;
- tick = 600*1000;
- break;
- case SC_FALCON:
- case SC_WEIGHT50:
- case SC_WEIGHT90:
- case SC_BROKNWEAPON:
- case SC_BROKNARMOR:
- tick=600*1000;
- break;
-
- case SC_AUTOGUARD:
- {
- int i,t;
- for(i=val2=0;i<val1;i++) {
- t = 5-(i>>1);
- val2 += (t < 0)? 1:t;
- }
- }
- break;
-
- case SC_DEFENDER:
- calc_flag = 1;
- val2 = 5 + val1*15;
- break;
-
- case SC_KEEPING:
- case SC_BARRIER:
- calc_flag = 1;
-
- case SC_HALLUCINATION:
- break;
-
- case SC_CONCENTRATION: /* ƒRƒ“ƒZƒ“ƒgƒŒ?ƒVƒ‡ƒ“ */
- *opt3 |= 1;
- calc_flag = 1;
- break;
-
- case SC_TENSIONRELAX: /* ƒeƒ“ƒVƒ‡ƒ“ƒŠƒ‰ƒbƒNƒX */
- calc_flag = 1;
- if(bl->type == BL_PC) {
- tick = 10000;
- }
- break;
-
- case SC_AURABLADE: /* ƒI?ƒ‰ƒuƒŒ?ƒh */
- case SC_PARRYING: /* ƒpƒŠƒCƒ“ƒO */
-// case SC_ASSUMPTIO: /* */
- case SC_HEADCRUSH: /* ƒwƒbƒhƒNƒ‰ƒbƒVƒ… */
- case SC_JOINTBEAT: /* ƒWƒ‡ƒCƒ“ƒgƒr?ƒg */
-// case SC_MARIONETTE: /* ƒ}ƒŠƒIƒlƒbƒgƒRƒ“ƒgƒ?ƒ‹ */
-
- //‚Ƃ肠‚¦‚¸Žè?‚«
- break;
-
-// -- moonsoul (for new upper class related skill status effects)
-/*
- case SC_AURABLADE:
- val2 = val1*10;
- break;
- case SC_PARRYING:
- val2=val1*3;
- break;
- case SC_CONCENTRATION:
- calc_flag=1;
- val2=val1*10;
- val3=val1*5;
- break;
- case SC_TENSIONRELAX:
-// val2 = 10;
-// val3 = 15;
- break;
- case SC_BERSERK:
- calc_flag=1;
- break;
- case SC_ASSUMPTIO:
- if(sc_data[SC_KYRIE].timer!=-1 )
- skill_status_change_end(bl,SC_KYRIE,-1);
- break;
-*/
- case SC_WINDWALK: /* ƒEƒCƒ“ƒhƒEƒH?ƒN */
- calc_flag = 1;
- val2 = (val1 / 2); //Flee㸗¦
- break;
-
- case SC_BERSERK: /* ƒo?ƒT?ƒN */
- if(sd){
- sd->status.hp = sd->status.max_hp * 3;
- sd->status.sp = 0;
- clif_updatestatus(sd,SP_HP);
- clif_updatestatus(sd,SP_SP);
- clif_status_change(bl,SC_INCREASEAGI,1); /* ƒAƒCƒRƒ“•\ަ */
- }
- *opt3 |= 128;
- tick = 10000;
- calc_flag = 1;
- break;
-
- case SC_ASSUMPTIO: /* ƒAƒXƒ€ƒvƒeƒBƒI */
- *opt3 |= 2048;
- break;
-
- case SC_BASILICA: // [celest]
- break;
-
- case SC_MARIONETTE: /* ƒ}ƒŠƒIƒlƒbƒgƒRƒ“ƒgƒ?ƒ‹ */
- case SC_MARIONETTE2:
- calc_flag = 1;
- *opt3 |= 1024;
- break;
-
- case SC_MELTDOWN: /* ƒƒ‹ƒgƒ_ƒEƒ“ */
- case SC_CARTBOOST: /* ƒJ?ƒgƒu?ƒXƒg */
- case SC_TRUESIGHT: /* ƒgƒDƒ‹?ƒTƒCƒg */
- case SC_SPIDERWEB: /* ƒXƒpƒCƒ_?ƒEƒFƒbƒu */
- case SC_MAGICPOWER: /* –‚–@—Í?• */
- calc_flag = 1;
- break;
-
- case SC_REJECTSWORD: /* ƒŠƒWƒFƒNƒgƒ\?ƒh */
- val2 = 3; //3‰ñU?‚𒵂˕Ԃ·
- break;
-
- case SC_MEMORIZE: /* ƒƒ‚ƒ‰ƒCƒY */
- val2 = 3; //3‰ñ‰r¥‚ð1/3‚É‚·‚é
- break;
-
- case SC_GRAFFITI: /* ƒOƒ‰ƒtƒBƒeƒB */
- {
- struct skill_unit_group *sg = skill_unitsetting(bl,RG_GRAFFITI,val1,val2,val3,0);
- if(sg)
- val4 = (int)sg;
- }
- break;
-
- case SC_SPLASHER: /* ƒxƒiƒ€ƒXƒvƒ‰ƒbƒVƒƒ? */
- break;
-
- case SC_FOGWALL:
- val2 = 75;
- // calc_flag = 1; // not sure of effects yet [celest]
- break;
-
- case SC_BLOCKSKILL:
- if (!tick) tick = 60000;
- if (!val3) val3 = -1;
- break;
-
- case SC_SLOWDOWN:
- calc_flag = 1;
- break;
-
- case SC_LEADERSHIP:
- case SC_GLORYWOUNDS:
- case SC_SOULCOLD:
- case SC_HAWKEYES:
- tick = 1000;
- calc_flag = 1;
- //val4 = 1;
- break;
-
- case SC_REGENERATION:
- val1 = 2;
- case SC_BATTLEORDERS:
- tick = 60000; // 1 minute
- calc_flag = 1;
- break;
+ nullpo_retr(1, bl);
- default:
- if(battle_config.error_log)
- printf("UnknownStatusChange [%d]\n", type);
+ if (bl->type == BL_PC) {
+ nullpo_retr(1, sd = (struct map_session_data *)bl);
+ if (!battle_config.pc_cloak_check_type) // If it's No it shouldn't be checked
return 0;
- }
-
- if(bl->type==BL_PC && type<SC_SENDMAX)
- clif_status_change(bl,type,1); /* ƒAƒCƒRƒ“•\ަ */
-
- /* option‚Ì?X */
- switch(type){
- case SC_STONE:
- case SC_FREEZE:
- case SC_STAN:
- case SC_SLEEP:
- battle_stopattack(bl); /* U?’âŽ~ */
- skill_stop_dancing(bl,0); /* ‰‰‘t/ƒ_ƒ“ƒX‚Ì’†? */
- { /* “¯Žž‚ÉŠ|‚©‚ç‚È‚¢ƒXƒe?ƒ^ƒXˆÙí‚ð‰ðœ */
- int i;
- for(i = SC_STONE; i <= SC_SLEEP; i++){
- if(sc_data[i].timer != -1){
- (*sc_count)--;
- delete_timer(sc_data[i].timer, skill_status_change_timer);
- sc_data[i].timer = -1;
- }
- }
- }
- if(type == SC_STONE)
- *opt1 = 6;
- else
- *opt1 = type - SC_STONE + 1;
- opt_flag = 1;
- break;
- case SC_POISON:
- case SC_CURSE:
- case SC_SILENCE:
- case SC_BLIND:
- *opt2 |= 1<<(type-SC_POISON);
- opt_flag = 1;
- break;
- case SC_DPOISON: // Žb’肜ł̃GƒtƒFƒNƒg‚ðŽg—p
- *opt2 |= 1;
- opt_flag = 1;
- break;
- case SC_SIGNUMCRUCIS:
- *opt2 |= 0x40;
- opt_flag = 1;
- break;
- case SC_HIDING:
- case SC_CLOAKING:
- battle_stopattack(bl); /* U?’âŽ~ */
- *option |= ((type==SC_HIDING)?2:4);
- opt_flag =1 ;
- break;
- case SC_CHASEWALK:
- battle_stopattack(bl); /* U?’âŽ~ */
- *option |= 16388;
- opt_flag =1 ;
- break;
- case SC_SIGHT:
- *option |= 1;
- opt_flag = 1;
- break;
- case SC_RUWACH:
- *option |= 8192;
- opt_flag = 1;
- break;
- case SC_WEDDING:
- *option |= 4096;
- opt_flag = 1;
- }
-
- if(opt_flag) /* option‚Ì?X */
- clif_changeoption(bl);
-
- (*sc_count)++; /* ƒXƒe?ƒ^ƒXˆÙí‚Ì? */
-
- sc_data[type].val1 = val1;
- sc_data[type].val2 = val2;
- sc_data[type].val3 = val3;
- sc_data[type].val4 = val4;
- /* ƒ^ƒCƒ}?Ý’è */
- sc_data[type].timer = add_timer(
- gettick() + tick, skill_status_change_timer, bl->id, type);
-
- if(bl->type==BL_PC && calc_flag)
- pc_calcstatus(sd,0); /* ƒXƒe?ƒ^ƒXÄŒvŽZ */
-
- if(bl->type==BL_PC && save_flag)
- chrif_save(sd); // save the player status
-
- if(bl->type==BL_PC && updateflag)
- clif_updatestatus(sd,updateflag); /* ƒXƒe?ƒ^ƒX‚ðƒNƒ‰ƒCƒAƒ“ƒg‚É‘—‚é */
-
- return 0;
-}
-/*==========================================
- * ƒXƒe?ƒ^ƒXˆÙí‘S‰ðœ
- *------------------------------------------
- */
-int skill_status_change_clear(struct block_list *bl, int type)
-{
- struct status_change* sc_data;
- short *sc_count, *option, *opt1, *opt2, *opt3;
- int i;
-
- nullpo_retr(0, bl);
- nullpo_retr(0, sc_data = battle_get_sc_data(bl));
- nullpo_retr(0, sc_count = battle_get_sc_count(bl));
- nullpo_retr(0, option = battle_get_option(bl));
- nullpo_retr(0, opt1 = battle_get_opt1(bl));
- nullpo_retr(0, opt2 = battle_get_opt2(bl));
- nullpo_retr(0, opt3 = battle_get_opt3(bl));
-
- if (*sc_count == 0)
+ } else if (bl->type == BL_MOB && !battle_config.monster_cloak_check_type)
return 0;
- for(i = 0; i < MAX_STATUSCHANGE; i++){
- if(sc_data[i].timer != -1){ /* ˆÙ킪‚ ‚é‚È‚çƒ^ƒCƒ}?‚ð휂·‚é */
-/*
- delete_timer(sc_data[i].timer, skill_status_change_timer);
- sc_data[i].timer = -1;
-
- if (!type && i < SC_SENDMAX)
- clif_status_change(bl, i, 0);
-*/
-
- skill_status_change_end(bl, i, -1);
- }
- }
- *sc_count = 0;
- *opt1 = 0;
- *opt2 = 0;
- *opt3 = 0;
- *option &= OPTION_MASK;
-
- if (night_flag == 1 && type == BL_PC && !map[bl->m].flag.indoors && // by [Yor]
- !map[bl->m].flag.indoors && battle_config.night_darkness_level <= 0) // [celest]
- *opt2 |= STATE_BLIND;
- if(!type || type&2)
- clif_changeoption(bl);
-
- return 0;
-}
-
-/* ƒNƒ?ƒLƒ“ƒO?¸iŽü‚è‚Ɉړ®•s‰Â”\’n?‚ª‚ ‚é‚©j */
-int skill_check_cloaking(struct block_list *bl)
-{
- static int dx[]={ 0, 1, 0, -1, -1, 1, 1, -1}; //optimized by Lupus
- static int dy[]={-1, 0, 1, 0, -1, -1, 1, 1};
- int end=1,i;
-
- //missing sd [Found by Celest, commited by Aria]
- struct map_session_data *sd=(struct map_session_data *)bl;
-
- nullpo_retr(0, bl);
-
- if(bl->type == BL_PC && !battle_config.pc_cloak_check_type) // If it's No it shouldn't be checked
- return 0;
- else if(bl->type == BL_MOB && !battle_config.monster_cloak_check_type)
- return 0;
- for(i=0;i<sizeof(dx)/sizeof(dx[0]);i++){
- int c=map_getcell(bl->m,bl->x+dx[i],bl->y+dy[i]);
- if(c==1 || c==5) {
- end=0;
+ for (i = 0; i < 8; i++) {
+ if (map_getcell(bl->m, bl->x+dx[i], bl->y+dy[i], CELL_CHKNOPASS)) {
+ end = 0;
break;
}
}
if(end){
- if ((bl->type == BL_PC && pc_checkskill(sd,AS_CLOAKING)<3) || bl->type == BL_MOB) {
- skill_status_change_end(bl, SC_CLOAKING, -1);
- *battle_get_option(bl)&=~4; /* ”O‚Ì‚½‚ß‚Ì?— */
+ if ((sd && pc_checkskill(sd,AS_CLOAKING)<3) || bl->type == BL_MOB) {
+ status_change_end(bl, SC_CLOAKING, -1);
}
- else if (bl->type == BL_PC && sd->sc_data[SC_CLOAKING].val3 != 130) {
+ else if (sd && sd->sc_data[SC_CLOAKING].val3 != 130) {
sd->sc_data[SC_CLOAKING].val3 = 130;
- pc_calcspeed (sd);
+ status_calc_speed (sd);
}
}
else {
- if (bl->type == BL_PC && sd->sc_data[SC_CLOAKING].val3 != 103) {
+ if (sd && sd->sc_data[SC_CLOAKING].val3 != 103) {
sd->sc_data[SC_CLOAKING].val3 = 103;
- pc_calcspeed (sd);
+ status_calc_speed (sd);
}
}
- return end;
-}
-int skill_type_cloaking(struct block_list *bl)
-{
- static int dx[]={ 0, 1, 0, -1, -1, 1, 1, -1}; //optimized by Lupus
- static int dy[]={-1, 0, 1, 0, -1, -1, 1, 1};
- int i;
-
- nullpo_retr(0, bl);
- if(bl->type == BL_PC && battle_config.pc_cloak_check_type&1)
- return 0;
- else if(bl->type == BL_MOB && battle_config.monster_cloak_check_type&1)
- return 0;
- for(i=0; i<sizeof(dx)/sizeof(dx[0]); i++)
- {
- int c=map_getcell(bl->m,bl->x+dx[i],bl->y+dy[i]);
- if(c==1 || c==5)
- return 0;
- }
- return 1;
+ return end;
}
/*
@@ -10018,48 +8096,6 @@ int skill_type_cloaking(struct block_list *bl)
*/
/*==========================================
- * ‰‰‘t/ƒ_ƒ“ƒXƒXƒLƒ‹‚©‚Ç‚¤‚©”»’è
- * ˆø? ƒXƒLƒ‹ID
- * ?‚è ƒ_ƒ“ƒX‚¶‚á‚È‚¢=0 ‡‘t=2 ‚»‚êˆÈŠO‚̃_ƒ“ƒX=1
- *------------------------------------------
- */
-int skill_is_danceskill(int id)
-{
- int i;
- switch(id){
- case BD_LULLABY: /* ŽqŽç‰Ì */
- case BD_RICHMANKIM: /* ƒjƒˆƒ‹ƒh‚̉ƒ */
- case BD_ETERNALCHAOS: /* ‰i‰“‚̬“× */
- case BD_DRUMBATTLEFIELD: /* ?‘¾ŒÛ‚Ì‹¿‚« */
- case BD_RINGNIBELUNGEN: /* ƒj?ƒxƒ‹ƒ“ƒO‚ÌŽw—Ö */
- case BD_ROKISWEIL: /* ƒƒL‚Ì‹©‚Ñ */
- case BD_INTOABYSS: /* [•£‚Ì’†‚É */
- case BD_SIEGFRIED: /* •sŽ€g‚̃W?ƒNƒtƒŠ?ƒh */
- case BD_RAGNAROK: /* _?‚Ì?¨ */
- case CG_MOONLIT: /* ŒŽ–¾‚è‚Ìò‚É—Ž‚¿‚é‰Ô‚Ñ‚ç */
- i=2;
- break;
- case BA_DISSONANCE: /* •s‹¦˜a‰¹ */
- case BA_FROSTJOKE: /* Ц‚¢ƒWƒ‡?ƒN */
- case BA_WHISTLE: /* Œû“J */
- case BA_ASSASSINCROSS: /* —[—z‚̃AƒTƒVƒ“ƒNƒƒX */
- case BA_POEMBRAGI: /* ƒuƒ‰ƒM‚ÌŽ */
- case BA_APPLEIDUN: /* ƒCƒhƒDƒ“‚Ì—ÑŒç */
- case DC_UGLYDANCE: /* Ž©•ªŸŽè‚ȃ_ƒ“ƒX */
- case DC_SCREAM: /* ƒXƒNƒŠ?ƒ€ */
- case DC_HUMMING: /* ƒnƒ~ƒ“ƒO */
- case DC_DONTFORGETME: /* Ž„‚ð–Y‚ê‚È‚¢‚Åc */
- case DC_FORTUNEKISS: /* K‰^‚̃LƒX */
- case DC_SERVICEFORYOU: /* ƒT?ƒrƒXƒtƒH?ƒ†? */
- i=1;
- break;
- default:
- i=0;
- }
- return i;
-}
-
-/*==========================================
* ‰‰‘t/ƒ_ƒ“ƒX‚ð‚â‚ß‚é
* flag 1‚Ň‘t’†‚Ȃ瑊•û‚Ƀ†ƒjƒbƒg‚ð”C‚¹‚é
*
@@ -10069,47 +8105,47 @@ void skill_stop_dancing(struct block_list *src, int flag)
{
struct status_change* sc_data;
struct skill_unit_group* group;
+ short* sc_count;
nullpo_retv(src);
-
- sc_data=battle_get_sc_data(src);
- if(sc_data && sc_data[SC_DANCING].timer != -1) {
- group=(struct skill_unit_group *)sc_data[SC_DANCING].val2; //ƒ_ƒ“ƒX‚̃XƒLƒ‹ƒ†ƒjƒbƒgID‚Íval2‚É“ü‚Á‚Ä‚é
- if(group && src->type==BL_PC && sc_data && sc_data[SC_DANCING].val4){ //‡‘t’†?
- struct map_session_data* dsd=map_id2sd(sc_data[SC_DANCING].val4); //‘Š•û‚ÌsdŽæ“¾
- if(flag){ //ƒƒOƒAƒEƒg‚ȂǕЕû‚ª—Ž‚¿‚Ä‚à‰‰‘t‚ª??‚³‚ê‚é
- if(dsd && src->id == group->src_id){ //ƒOƒ‹?ƒv‚ðŽ‚Á‚Ä‚éPC‚ª—Ž‚¿‚é
- group->src_id=sc_data[SC_DANCING].val4; //‘Š•û‚ɃOƒ‹?ƒv‚ð”C‚¹‚é
- if(flag&1) //ƒƒOƒAƒEƒg
- dsd->sc_data[SC_DANCING].val4=0; //‘Š•û‚Ì‘Š•û‚ð0‚É‚µ‚ć‘tI—¹¨’Êí‚̃_ƒ“ƒX?‘Ô
- if(flag&2) //ƒnƒG”ò‚тȂÇ
- return; //‡‘t‚àƒ_ƒ“ƒX?‘Ô‚àI—¹‚³‚¹‚È‚¢•ƒXƒLƒ‹ƒ†ƒjƒbƒg‚Í’u‚¢‚Ä‚¯‚Ú‚è
- }else if(dsd && dsd->bl.id == group->src_id){ //‘Š•û‚ªƒOƒ‹?ƒv‚ðŽ‚Á‚Ä‚¢‚éPC‚ª—Ž‚¿‚é(Ž©•ª‚̓Oƒ‹?ƒv‚ðŽ‚Á‚Ä‚¢‚È‚¢)
- if(flag&1) //ƒƒOƒAƒEƒg
- dsd->sc_data[SC_DANCING].val4=0; //‘Š•û‚Ì‘Š•û‚ð0‚É‚µ‚ć‘tI—¹¨’Êí‚̃_ƒ“ƒX?‘Ô
- if(flag&2) //ƒnƒG”ò‚тȂÇ
- return; //‡‘t‚àƒ_ƒ“ƒX?‘Ô‚àI—¹‚³‚¹‚È‚¢•ƒXƒLƒ‹ƒ†ƒjƒbƒg‚Í’u‚¢‚Ä‚¯‚Ú‚è
+ nullpo_retv(sc_data = status_get_sc_data(src));
+ nullpo_retv(sc_count = status_get_sc_count(src));
+
+ if((*sc_count) > 0 && sc_data[SC_DANCING].timer != -1) {
+ group = (struct skill_unit_group *)sc_data[SC_DANCING].val2; //ƒ_ƒ“ƒX‚̃XƒLƒ‹ƒ†ƒjƒbƒgID‚Íval2‚É“ü‚Á‚Ä‚é
+ if (src->type == BL_PC) {
+ if (group && sc_data[SC_DANCING].val4){ //‡‘t’†?
+ struct map_session_data* dsd = map_id2sd(sc_data[SC_DANCING].val4); //‘Š•û‚ÌsdŽæ“¾
+ if (flag && dsd) { //ƒƒOƒAƒEƒg‚ȂǕЕû‚ª—Ž‚¿‚Ä‚à‰‰‘t‚ª??‚³‚ê‚é
+ if (src->id == group->src_id) { //ƒOƒ‹?ƒv‚ðŽ‚Á‚Ä‚éPC‚ª—Ž‚¿‚é
+ group->src_id = sc_data[SC_DANCING].val4; //‘Š•û‚ɃOƒ‹?ƒv‚ð”C‚¹‚é
+ if (flag & 1) //ƒƒOƒAƒEƒg
+ dsd->sc_data[SC_DANCING].val4 = 0; //‘Š•û‚Ì‘Š•û‚ð0‚É‚µ‚ć‘tI—¹¨’Êí‚̃_ƒ“ƒX?‘Ô
+ if(flag & 2) //ƒnƒG”ò‚тȂÇ
+ return; //‡‘t‚àƒ_ƒ“ƒX?‘Ô‚àI—¹‚³‚¹‚È‚¢•ƒXƒLƒ‹ƒ†ƒjƒbƒg‚Í’u‚¢‚Ä‚¯‚Ú‚è
+ } else if (dsd->bl.id == group->src_id) { //‘Š•û‚ªƒOƒ‹?ƒv‚ðŽ‚Á‚Ä‚¢‚éPC‚ª—Ž‚¿‚é(Ž©•ª‚̓Oƒ‹?ƒv‚ðŽ‚Á‚Ä‚¢‚È‚¢)
+ if (flag & 1) //ƒƒOƒAƒEƒg
+ dsd->sc_data[SC_DANCING].val4 = 0; //‘Š•û‚Ì‘Š•û‚ð0‚É‚µ‚ć‘tI—¹¨’Êí‚̃_ƒ“ƒX?‘Ô
+ if(flag & 2) //ƒnƒG”ò‚тȂÇ
+ return; //‡‘t‚àƒ_ƒ“ƒX?‘Ô‚àI—¹‚³‚¹‚È‚¢•ƒXƒLƒ‹ƒ†ƒjƒbƒg‚Í’u‚¢‚Ä‚¯‚Ú‚è
+ }
+ status_change_end(src, SC_DANCING, -1); //Ž©•ª‚̃Xƒe?ƒ^ƒX‚ðI—¹‚³‚¹‚é
+ //‚»‚µ‚ăOƒ‹?ƒv‚ÍÁ‚³‚È‚¢•Á‚³‚È‚¢‚̂ŃXƒe?ƒ^ƒXŒvŽZ‚à‚¢‚ç‚È‚¢H
+ return;
+ } else if (dsd) {
+ if (src->id == group->src_id) //ƒOƒ‹?ƒv‚ðŽ‚Á‚Ä‚éPC‚ªŽ~‚ß‚é
+ status_change_end(&dsd->bl, SC_DANCING, -1); //‘ŠŽè‚̃Xƒe?ƒ^ƒX‚ðI—¹‚³‚¹‚é
+ if(dsd->bl.id == group->src_id) //‘Š•û‚ªƒOƒ‹?ƒv‚ðŽ‚Á‚Ä‚¢‚éPC‚ªŽ~‚ß‚é(Ž©•ª‚̓Oƒ‹?ƒv‚ðŽ‚Á‚Ä‚¢‚È‚¢)
+ status_change_end(src, SC_DANCING, -1); //Ž©•ª‚̃Xƒe?ƒ^ƒX‚ðI—¹‚³‚¹‚é
}
- skill_status_change_end(src,SC_DANCING,-1);//Ž©•ª‚̃Xƒe?ƒ^ƒX‚ðI—¹‚³‚¹‚é
- //‚»‚µ‚ăOƒ‹?ƒv‚ÍÁ‚³‚È‚¢•Á‚³‚È‚¢‚̂ŃXƒe?ƒ^ƒXŒvŽZ‚à‚¢‚ç‚È‚¢H
+ }
+ if(flag & 2 && group) { //ƒnƒG‚Å”ò‚ñ‚¾‚Æ‚«‚Æ‚©‚̓†ƒjƒbƒg‚à”ò‚Ô
+ struct map_session_data *sd = (struct map_session_data *)src;
+ if (sd) skill_unit_move_unit_group(group, sd->bl.m, (sd->to_x - sd->bl.x), (sd->to_y - sd->bl.y));
return;
- }else{
- if(dsd && src->id == group->src_id){ //ƒOƒ‹?ƒv‚ðŽ‚Á‚Ä‚éPC‚ªŽ~‚ß‚é
- skill_status_change_end((struct block_list *)dsd,SC_DANCING,-1);//‘ŠŽè‚̃Xƒe?ƒ^ƒX‚ðI—¹‚³‚¹‚é
- }
- if(dsd && dsd->bl.id == group->src_id){ //‘Š•û‚ªƒOƒ‹?ƒv‚ðŽ‚Á‚Ä‚¢‚éPC‚ªŽ~‚ß‚é(Ž©•ª‚̓Oƒ‹?ƒv‚ðŽ‚Á‚Ä‚¢‚È‚¢)
- skill_status_change_end(src,SC_DANCING,-1);//Ž©•ª‚̃Xƒe?ƒ^ƒX‚ðI—¹‚³‚¹‚é
- }
}
}
- if(flag&2 && group && src->type==BL_PC){ //ƒnƒG‚Å”ò‚ñ‚¾‚Æ‚«‚Æ‚©‚̓†ƒjƒbƒg‚à”ò‚Ô
- struct map_session_data *sd = (struct map_session_data *)src;
- skill_unit_move_unit_group(group, sd->bl.m,(sd->to_x - sd->bl.x),(sd->to_y - sd->bl.y));
- return;
- }
skill_delunitgroup(group);
- if(src->type==BL_PC)
- pc_calcstatus((struct map_session_data *)src,0);
}
}
@@ -10138,10 +8174,13 @@ struct skill_unit *skill_initunit(struct skill_unit_group *group,int idx,int x,i
map_addblock(&unit->bl);
clif_skill_setunit(unit);
+
+ if (group->skill_id==HP_BASILICA)
+ skill_basilica_cell(unit,CELL_SETBASILICA);
+
return unit;
}
-int skill_unit_timer_sub_ondelete( struct block_list *bl, va_list ap );
/*==========================================
* ƒXƒLƒ‹ƒ†ƒjƒbƒgíœ
*------------------------------------------
@@ -10149,7 +8188,6 @@ int skill_unit_timer_sub_ondelete( struct block_list *bl, va_list ap );
int skill_delunit(struct skill_unit *unit)
{
struct skill_unit_group *group;
- int range;
nullpo_retr(0, unit);
if(!unit->alive)
@@ -10159,11 +8197,15 @@ int skill_delunit(struct skill_unit *unit)
/* onlimitƒCƒxƒ“ƒgŒÄ‚Ño‚µ */
skill_unit_onlimit( unit,gettick() );
- /* ondeleteƒCƒxƒ“ƒgŒÄ‚Ño‚µ */
- range=group->range;
- map_foreachinarea( skill_unit_timer_sub_ondelete, unit->bl.m,
- unit->bl.x-range,unit->bl.y-range,unit->bl.x+range,unit->bl.y+range,0,
- &unit->bl,gettick() );
+ /* onoutƒCƒxƒ“ƒgŒÄ‚Ño‚µ */
+ if (!unit->range) {
+ map_foreachinarea(skill_unit_effect,unit->bl.m,
+ unit->bl.x,unit->bl.y,unit->bl.x,unit->bl.y,0,
+ &unit->bl,gettick(),0);
+ }
+
+ if (group->skill_id==HP_BASILICA)
+ skill_basilica_cell(unit,CELL_CLRBASILICA);
clif_skill_delunit(unit);
@@ -10179,7 +8221,7 @@ int skill_delunit(struct skill_unit *unit)
* ƒXƒLƒ‹ƒ†ƒjƒbƒgƒOƒ‹?ƒv‰Šú‰»
*------------------------------------------
*/
-static int skill_unit_group_newid=10;
+static int skill_unit_group_newid = MAX_SKILL_DB;
struct skill_unit_group *skill_initunitgroup(struct block_list *src,
int count,int skillid,int skilllv,int unit_id)
{
@@ -10227,11 +8269,11 @@ struct skill_unit_group *skill_initunitgroup(struct block_list *src,
}
group->src_id=src->id;
- group->party_id=battle_get_party_id(src);
- group->guild_id=battle_get_guild_id(src);
+ group->party_id=status_get_party_id(src);
+ group->guild_id=status_get_guild_id(src);
group->group_id=skill_unit_group_newid++;
if(skill_unit_group_newid<=0)
- skill_unit_group_newid=10;
+ skill_unit_group_newid = MAX_SKILL_DB;
group->unit=(struct skill_unit *)aCalloc(count,sizeof(struct skill_unit));
group->unit_count=count;
group->val1=group->val2=0;
@@ -10239,39 +8281,23 @@ struct skill_unit_group *skill_initunitgroup(struct block_list *src,
group->skill_lv=skilllv;
group->unit_id=unit_id;
group->map=src->m;
- group->range=0;
group->limit=10000;
group->interval=1000;
group->tick=gettick();
group->valstr=NULL;
- if( skill_is_danceskill(skillid) ){
+ if (skill_get_unit_flag(skillid)&UF_DANCE) {
struct map_session_data *sd = NULL;
if(src->type==BL_PC && (sd=(struct map_session_data *)src) ){
sd->skillid_dance=skillid;
sd->skilllv_dance=skilllv;
}
- skill_status_change_start(src,SC_DANCING,skillid,(int)group,0,0,skill_get_time(skillid,skilllv)+1000,0);
- switch(skillid){ //‡‘tƒXƒLƒ‹‚Í‘Š•û‚ðƒ_ƒ“ƒX?‘Ô‚É‚·‚é
- case BD_LULLABY: /* ŽqŽç‰Ì */
- case BD_RICHMANKIM: /* ƒjƒˆƒ‹ƒh‚̉ƒ */
- case BD_ETERNALCHAOS: /* ‰i‰“‚̬“× */
- case BD_DRUMBATTLEFIELD: /* ?‘¾ŒÛ‚Ì‹¿‚« */
- case BD_RINGNIBELUNGEN: /* ƒj?ƒxƒ‹ƒ“ƒO‚ÌŽw—Ö */
- case BD_ROKISWEIL: /* ƒƒL‚Ì‹©‚Ñ */
- case BD_INTOABYSS: /* [•£‚Ì’†‚É */
- case BD_SIEGFRIED: /* •sŽ€g‚̃W?ƒNƒtƒŠ?ƒh */
- case BD_RAGNAROK: /* _?‚Ì?¨ */
- case CG_MOONLIT: /* ŒŽ–¾‚è‚Ìò‚É—Ž‚¿‚é‰Ô‚Ñ‚ç */
- {
- int range=1;
- int c=0;
- if(sd){
- map_foreachinarea(skill_check_condition_use_sub,sd->bl.m,
- sd->bl.x-range,sd->bl.y-range,
- sd->bl.x+range,sd->bl.y+range,BL_PC,&sd->bl,&c);
- }
- }
+ status_change_start(src,SC_DANCING,skillid,(int)group,0,0,skill_get_time(skillid,skilllv)+1000,0);
+ //‡‘tƒXƒLƒ‹‚Í‘Š•û‚ðƒ_ƒ“ƒXó‘Ô‚É‚·‚é
+ if (sd && skill_get_unit_flag(skillid)&UF_ENSEMBLE) {
+ int c=0;
+ map_foreachinarea(skill_check_condition_use_sub,sd->bl.m,
+ sd->bl.x-1,sd->bl.y-1,sd->bl.x+1,sd->bl.y+1,BL_PC,&sd->bl,&c);
}
}
return group;
@@ -10291,10 +8317,16 @@ int skill_delunitgroup(struct skill_unit_group *group)
return 0;
src=map_id2bl(group->src_id);
- if( skill_is_danceskill(group->skill_id) ){ //ƒ_ƒ“ƒXƒXƒLƒ‹‚̓_ƒ“ƒX?‘Ô‚ð‰ðœ‚·‚é
- if(src)
- skill_status_change_end(src,SC_DANCING,-1);
+ //ƒ_ƒ“ƒXƒXƒLƒ‹‚̓_ƒ“ƒXó‘Ô‚ð‰ðœ‚·‚é
+ if(src) {
+ if (skill_get_unit_flag(group->skill_id)&UF_DANCE)
+ status_change_end(src,SC_DANCING,-1);
+ if (group->unit_id == 0x86) {
+ struct status_change *sc_data = status_get_sc_data(src);
+ if(sc_data && sc_data[SC_MAGICPOWER].timer != -1) //ƒ}ƒWƒbƒNƒpƒ?‚Ì?‰ÊI—¹
+ status_change_end(src,SC_MAGICPOWER,-1);
}
+ }
group->alive_count=0;
if(group->unit!=NULL){
@@ -10307,7 +8339,7 @@ int skill_delunitgroup(struct skill_unit_group *group)
group->valstr=NULL;
}
- map_freeblock(group->unit); /* free()‚̑ւí‚è */
+ map_freeblock(group->unit); /* aFree()‚̑ւí‚è */
group->unit=NULL;
group->src_id=0;
group->group_id=0;
@@ -10329,13 +8361,14 @@ int skill_clear_unitgroup(struct block_list *src)
if(src->type==BL_PC){
group=((struct map_session_data *)src)->skillunit;
maxsug=MAX_SKILLUNITGROUP;
- }else if(src->type==BL_MOB){
+ } else if(src->type==BL_MOB){
group=((struct mob_data *)src)->skillunit;
maxsug=MAX_MOBSKILLUNITGROUP;
- }else if(src->type==BL_PET){ // [Valaris]
+ } else if(src->type==BL_PET){ // [Valaris]
group=((struct pet_data *)src)->skillunit;
maxsug=MAX_MOBSKILLUNITGROUP;
- }
+ } else
+ return 0;
if(group){
int i;
for(i=0;i<maxsug;i++)
@@ -10350,54 +8383,46 @@ int skill_clear_unitgroup(struct block_list *src)
*------------------------------------------
*/
struct skill_unit_group_tickset *skill_unitgrouptickset_search(
- struct block_list *bl,int group_id)
+ struct block_list *bl,struct skill_unit_group *group,int tick)
{
- int i,j=0,k,s=group_id%MAX_SKILLUNITGROUPTICKSET;
- struct skill_unit_group_tickset *set=NULL;
+ int i,j=-1,k,s,id;
+ struct skill_unit_group_tickset *set;
nullpo_retr(0, bl);
+ if (group->interval==-1)
+ return NULL;
- if(bl->type==BL_PC){
- set=((struct map_session_data *)bl)->skillunittick;
- }else{
- set=((struct mob_data *)bl)->skillunittick;
- }
- if(set==NULL)
+ if (bl->type == BL_PC)
+ set = ((struct map_session_data *)bl)->skillunittick;
+ else if (bl->type == BL_MOB)
+ set = ((struct mob_data *)bl)->skillunittick;
+ else
return 0;
- for(i=0;i<MAX_SKILLUNITGROUPTICKSET;i++)
- if( set[(k=(i+s)%MAX_SKILLUNITGROUPTICKSET)].group_id == group_id )
- return &set[k];
- else if( set[k].group_id==0 )
- j=k;
- return &set[j];
-}
-
-/*==========================================
- * ƒXƒLƒ‹ƒ†ƒjƒbƒgƒOƒ‹?ƒv‚Ì”í‰e‹¿tickíœ
- *------------------------------------------
- */
-int skill_unitgrouptickset_delete(struct block_list *bl,int group_id)
-{
- int i,s=group_id%MAX_SKILLUNITGROUPTICKSET;
- struct skill_unit_group_tickset *set=NULL,*ts;
-
- nullpo_retr(0, bl);
+ if (skill_get_unit_flag(group->skill_id)&UF_NOOVERLAP)
+ id = s = group->skill_id;
+ else
+ id = s = group->group_id;
- if(bl->type==BL_PC){
- set=((struct map_session_data *)bl)->skillunittick;
- }else{
- set=((struct mob_data *)bl)->skillunittick;
+ for (i=0; i<MAX_SKILLUNITGROUPTICKSET; i++) {
+ k = (i+s) % MAX_SKILLUNITGROUPTICKSET;
+ if (set[k].id == id)
+ return &set[k];
+ else if (j==-1 && (DIFF_TICK(tick,set[k].tick)>0 || set[k].id==0))
+ j=k;
}
- if(set!=NULL){
-
- for(i=0;i<MAX_SKILLUNITGROUPTICKSET;i++)
- if( (ts=&set[(i+s)%MAX_SKILLUNITGROUPTICKSET])->group_id == group_id )
- ts->group_id=0;
-
+ if (j == -1) {
+ if(battle_config.error_log) {
+ sprintf (tmp_output, "skill_unitgrouptickset_search: tickset is full\n");
+ ShowWarning (tmp_output);
+ }
+ j = id % MAX_SKILLUNITGROUPTICKSET;
}
- return 0;
+
+ set[j].id = id;
+ set[j].tick = tick;
+ return &set[j];
}
/*==========================================
@@ -10406,49 +8431,27 @@ int skill_unitgrouptickset_delete(struct block_list *bl,int group_id)
*/
int skill_unit_timer_sub_onplace( struct block_list *bl, va_list ap )
{
- struct block_list *src;
- struct skill_unit *su;
+ struct skill_unit *unit;
+ struct skill_unit_group *group;
unsigned int tick;
nullpo_retr(0, bl);
nullpo_retr(0, ap);
- src=va_arg(ap,struct block_list*);
-
- tick=va_arg(ap,unsigned int);
- su = (struct skill_unit *)src;
+ unit = va_arg(ap,struct skill_unit *);
+ tick = va_arg(ap,unsigned int);
- if( su && su->alive ) {
- struct skill_unit_group *sg;
- sg = su->group;
- if(sg && battle_check_target(src,bl,sg->target_flag )>0)
- skill_unit_onplace( su, bl, tick );
- }
- return 0;
-}
+ if (bl->type!=BL_PC && bl->type!=BL_MOB)
+ return 0;
+ if (!unit->alive || bl->prev==NULL)
+ return 0;
-/*==========================================
- * ƒXƒLƒ‹ƒ†ƒjƒbƒgƒ^ƒCƒ}?íœ?——p(foreachinarea)
- *------------------------------------------
- */
-int skill_unit_timer_sub_ondelete( struct block_list *bl, va_list ap )
-{
- struct block_list *src;
- struct skill_unit *su;
- unsigned int tick;
+ nullpo_retr(0, group=unit->group);
- nullpo_retr(0, bl);
- nullpo_retr(0, ap);
- src=va_arg(ap,struct block_list*);
+ if (battle_check_target(&unit->bl,bl,group->target_flag)<=0)
+ return 0;
- tick=va_arg(ap,unsigned int);
- su = (struct skill_unit *)src;
+ skill_unit_onplace_timer(unit,bl,tick);
- if( su && su->alive ){
- struct skill_unit_group *sg;
- sg = su->group;
- if( sg && battle_check_target(src,bl,sg->target_flag )>0 )
- skill_unit_ondelete( su, bl, tick );
- }
return 0;
}
@@ -10466,28 +8469,38 @@ int skill_unit_timer_sub( struct block_list *bl, va_list ap )
nullpo_retr(0, bl);
nullpo_retr(0, ap);
nullpo_retr(0, unit=(struct skill_unit *)bl);
- nullpo_retr(0, group=unit->group);
tick=va_arg(ap,unsigned int);
if(!unit->alive)
return 0;
+ group=unit->group;
- range=(unit->range!=0)?unit->range:group->range;
+ nullpo_retr(0, group);
+ range = unit->range;
- /* onplaceƒCƒxƒ“ƒgŒÄ‚Ño‚µ */
- if(unit->alive && unit->range>=0){
- map_foreachinarea( skill_unit_timer_sub_onplace, bl->m,
- bl->x-range,bl->y-range,bl->x+range,bl->y+range,0,
- bl,tick);
- if(group->unit_id == 0xaa && DIFF_TICK(tick,group->tick)>=6000*group->val2){
- map_foreachinarea( skill_idun_heal, bl->m,
- bl->x-range,bl->y-range,bl->x+range,bl->y+range,0,unit);
- group->val2++;
+ /* onplace_timerƒCƒxƒ“ƒgŒÄ‚Ño‚µ */
+ if (range>=0 && group->interval!=-1) {
+ map_foreachinarea(skill_unit_timer_sub_onplace, bl->m,
+ bl->x-range,bl->y-range,bl->x+range,bl->y+range,0,bl,tick);
+ if (!unit->alive)
+ return 0;
+ // ƒ}ƒOƒkƒX‚Í”­“®‚µ‚½ƒ†ƒjƒbƒg‚Í휂·‚é
+ if (group->skill_id==PR_MAGNUS && unit->val2) {
+ skill_delunit(unit);
+ return 0;
}
}
+ // ƒCƒhƒDƒ“‚Ì—ÑŒç‚É‚æ‚é‰ñ•œ
+ if (group->unit_id==0xaa && DIFF_TICK(tick,group->tick)>=6000*group->val3) {
+ struct block_list *src = map_id2bl(group->src_id);
+ int range = skill_get_unit_layout_type(group->skill_id,group->skill_lv);
+ nullpo_retr(0, src);
+ map_foreachinarea(skill_idun_heal,src->m,
+ src->x-range,src->y-range,src->x+range,src->y+range,0,unit);
+ group->val3++;
+ }
/* ŽžŠÔØ‚êíœ */
- if(unit->alive &&
- (DIFF_TICK(tick,group->tick)>=group->limit || DIFF_TICK(tick,group->tick)>=unit->limit) ){
+ if((DIFF_TICK(tick,group->tick)>=group->limit || DIFF_TICK(tick,group->tick)>=unit->limit)){
switch(group->unit_id){
case 0x8f: /* ƒuƒ‰ƒXƒgƒ}ƒCƒ“ */
group->unit_id = 0x8c;
@@ -10516,7 +8529,21 @@ int skill_unit_timer_sub( struct block_list *bl, va_list ap )
map_addflooritem(&item_tmp,1,bl->m,bl->x,bl->y,NULL,NULL,NULL,0); // ?•ÔŠÒ
}
}
+ skill_delunit(unit);
}
+ break;
+
+ case 0xc1:
+ case 0xc2:
+ case 0xc3:
+ case 0xc4:
+ {
+ struct block_list *src=map_id2bl(group->src_id);
+ if (src)
+ group->tick = tick;
+ }
+ break;
+
default:
skill_delunit(unit);
}
@@ -10549,92 +8576,33 @@ int skill_unit_timer( int tid,unsigned int tick,int id,int data)
* ƒXƒLƒ‹ƒ†ƒjƒbƒgˆÚ“®Žž?——p(foreachinarea)
*------------------------------------------
*/
-int skill_unit_out_all_sub( struct block_list *bl, va_list ap )
-{
- struct skill_unit *unit;
- struct skill_unit_group *group;
- struct block_list *src;
- int range;
- unsigned int tick;
-
- nullpo_retr(0, bl);
- nullpo_retr(0, ap);
- nullpo_retr(0, src=va_arg(ap,struct block_list*));
- nullpo_retr(0, unit=(struct skill_unit *)bl);
- nullpo_retr(0, group=unit->group);
-
- tick=va_arg(ap,unsigned int);
-
- if(!unit->alive || src->prev==NULL)
- return 0;
-
- range=(unit->range!=0)?unit->range:group->range;
-
- if( range<0 || battle_check_target(bl,src,group->target_flag )<=0 )
- return 0;
-
- if( src->x >= bl->x-range && src->x <= bl->x+range &&
- src->y >= bl->y-range && src->y <= bl->y+range )
- skill_unit_onout( unit, src, tick );
-
- return 0;
-}
-
-
-/*==========================================
- * ƒXƒLƒ‹ƒ†ƒjƒbƒgˆÚ“®Žž?—
- *------------------------------------------
- */
-int skill_unit_out_all( struct block_list *bl,unsigned int tick,int range)
-{
- nullpo_retr(0, bl);
-
- if( bl->prev==NULL )
- return 0;
-
- if(range<7)
- range=7;
- map_foreachinarea( skill_unit_out_all_sub,
- bl->m,bl->x-range,bl->y-range,bl->x+range,bl->y+range,BL_SKILL,
- bl,tick );
-
- return 0;
-}
-
-/*==========================================
- * ƒXƒLƒ‹ƒ†ƒjƒbƒgˆÚ“®Žž?——p(foreachinarea)
- *------------------------------------------
- */
int skill_unit_move_sub( struct block_list *bl, va_list ap )
{
- struct skill_unit *unit;
+ struct skill_unit *unit = (struct skill_unit *)bl;
struct skill_unit_group *group;
- struct block_list *src;
- int range;
- unsigned int tick;
+ struct block_list *target;
+ unsigned int tick,flag;
nullpo_retr(0, bl);
nullpo_retr(0, ap);
- nullpo_retr(0, unit=(struct skill_unit *)bl);
- nullpo_retr(0, src=va_arg(ap,struct block_list*));
-
- tick=va_arg(ap,unsigned int);
+ nullpo_retr(0, target=va_arg(ap,struct block_list*));
+ tick = va_arg(ap,unsigned int);
+ flag = va_arg(ap,int);
- if(!unit->alive || src->prev==NULL)
+ if (target->type!=BL_PC && target->type!=BL_MOB)
return 0;
- if((group=unit->group) == NULL)
+ nullpo_retr(0, group=unit->group);
+ if (group->interval!=-1)
return 0;
- range=(unit->range!=0)?unit->range:group->range;
- if( range<0 || battle_check_target(bl,src,group->target_flag )<=0 )
+ if (!unit->alive || target->prev==NULL)
return 0;
- if( src->x >= bl->x-range && src->x <= bl->x+range &&
- src->y >= bl->y-range && src->y <= bl->y+range )
- skill_unit_onplace( unit, src, tick );
+ if (flag)
+ skill_unit_onplace(unit,target,tick);
else
- skill_unit_onout( unit, src, tick );
+ skill_unit_onout(unit,target,tick);
return 0;
}
@@ -10643,173 +8611,117 @@ int skill_unit_move_sub( struct block_list *bl, va_list ap )
* ƒXƒLƒ‹ƒ†ƒjƒbƒgˆÚ“®Žž?—
*------------------------------------------
*/
-int skill_unit_move( struct block_list *bl,unsigned int tick,int range)
+int skill_unit_move(struct block_list *bl,unsigned int tick,int flag)
{
nullpo_retr(0, bl);
- if( bl->prev==NULL )
+ if(bl->prev==NULL )
return 0;
- if(range<7)
- range=7;
- map_foreachinarea( skill_unit_move_sub,
- bl->m,bl->x-range,bl->y-range,bl->x+range,bl->y+range,BL_SKILL,
- bl,tick );
+ map_foreachinarea(skill_unit_move_sub,
+ bl->m,bl->x,bl->y,bl->x,bl->y,BL_SKILL,bl,tick,flag);
return 0;
}
/*==========================================
- * ƒXƒLƒ‹ƒ†ƒjƒbƒgŽ©?‚̈ړ®Žž?—(foreachinarea)
- *------------------------------------------
- */
-int skill_unit_move_unit_group_sub( struct block_list *bl, va_list ap )
-{
- struct skill_unit *unit;
- struct skill_unit_group *group;
- struct block_list *src;
- int range;
- unsigned int tick;
-
- nullpo_retr(0, bl);
- nullpo_retr(0, ap);
- nullpo_retr(0, src=va_arg(ap,struct block_list*));
- nullpo_retr(0, unit=(struct skill_unit *)src);
- nullpo_retr(0, group=unit->group);
-
- tick=va_arg(ap,unsigned int);
-
- if(!unit->alive || bl->prev==NULL)
- return 0;
-
- range=(unit->range!=0)?unit->range:group->range;
-
- if( range<0 || battle_check_target(src,bl,group->target_flag )<=0 )
- return 0;
- if( bl->x >= src->x-range && bl->x <= src->x+range &&
- bl->y >= src->y-range && bl->y <= src->y+range )
- skill_unit_onplace( unit, bl, tick );
- else
- skill_unit_onout( unit, bl, tick );
- return 0;
-}
-
-/*==========================================
* ƒXƒLƒ‹ƒ†ƒjƒbƒgŽ©?‚̈ړ®Žž?—
* ˆø?‚̓Oƒ‹?ƒv‚ƈړ®—Ê
*------------------------------------------
*/
int skill_unit_move_unit_group( struct skill_unit_group *group, int m,int dx,int dy)
{
+ int i,j;
+ int tick = gettick();
+ int *m_flag;
+ struct skill_unit *unit1;
+ struct skill_unit *unit2;
+
nullpo_retr(0, group);
+ if (group->unit_count<=0)
+ return 0;
+ if (group->unit==NULL)
+ return 0;
- if( group->unit_count<=0)
+ // ˆÚ“®‰Â”\‚ȃXƒLƒ‹‚̓_ƒ“ƒXŒn‚ÆAƒuƒ‰ƒXƒgƒ}ƒCƒ“AƒNƒŒƒCƒ‚ƒA[ƒgƒ‰ƒbƒv‚Ì‚Ý
+ if (!(skill_get_unit_flag(group->skill_id)&UF_DANCE) &&
+ group->skill_id!=HT_CLAYMORETRAP && group->skill_id!=HT_BLASTMINE)
return 0;
- if(group->unit!=NULL){
- if(!battle_config.unit_movement_type){
- int i;
- for(i=0;i<group->unit_count;i++){
- struct skill_unit *unit=&group->unit[i];
- if(unit->alive && !(m==unit->bl.m && dx==0 && dy==0)){
- int range=unit->range;
- map_delblock(&unit->bl);
- unit->bl.m = m;
- unit->bl.x += dx;
- unit->bl.y += dy;
- map_addblock(&unit->bl);
- clif_skill_setunit(unit);
- if(range>0){
- if(range<7)
- range=7;
- map_foreachinarea( skill_unit_move_unit_group_sub, unit->bl.m,
- unit->bl.x-range,unit->bl.y-range,unit->bl.x+range,unit->bl.y+range,0,
- &unit->bl,gettick() );
- }
- }
+ m_flag = (int *) aMalloc(sizeof(int)*group->unit_count);
+ memset(m_flag,0,sizeof(int)*group->unit_count);// ˆÚ“®ƒtƒ‰ƒO
+ // æ‚Ƀtƒ‰ƒO‚ð‘S•”Œˆ‚ß‚é
+ // m_flag
+ // 0: ’PƒˆÚ“®
+ // 1: ƒ†ƒjƒbƒg‚ðˆÚ“®‚·‚é(Œ»ˆÊ’u‚©‚烆ƒjƒbƒg‚ª‚È‚­‚È‚é)
+ // 2: Žc—¯•VˆÊ’u‚ªˆÚ“®æ‚ƂȂé(ˆÚ“®æ‚Ƀ†ƒjƒbƒg‚ª‘¶Ý‚µ‚È‚¢)
+ // 3: Žc—¯
+ for(i=0;i<group->unit_count;i++){
+ unit1=&group->unit[i];
+ if (!unit1->alive || unit1->bl.m!=m)
+ continue;
+ for(j=0;j<group->unit_count;j++){
+ unit2=&group->unit[j];
+ if (!unit2->alive)
+ continue;
+ if (unit1->bl.x+dx==unit2->bl.x && unit1->bl.y+dy==unit2->bl.y){
+ // ˆÚ“®æ‚Ƀ†ƒjƒbƒg‚ª‚©‚Ô‚Á‚Ä‚¢‚é
+ m_flag[i] |= 0x1;
}
- }else{
- int i,j, *r_flag, *s_flag, *m_flag;
- struct skill_unit *unit1;
- struct skill_unit *unit2;
- r_flag = (int *) malloc(sizeof(int) * group->unit_count);
- s_flag = (int *) malloc(sizeof(int) * group->unit_count);
- m_flag = (int *) malloc(sizeof(int) * group->unit_count);
- memset(r_flag,0, sizeof(int) * group->unit_count);// ?³ƒtƒ‰ƒO
- memset(s_flag,0, sizeof(int) * group->unit_count);// ?³ƒtƒ‰ƒO
- memset(m_flag,0, sizeof(int) * group->unit_count);// ?³ƒtƒ‰ƒO
-
- //æ‚Ƀtƒ‰ƒO‚ð‘S•”Œˆ‚ß‚é
- for(i=0;i<group->unit_count;i++){
- int move_check=0;// ‚©‚Ô‚èƒtƒ‰ƒO
- unit1=&group->unit[i];
- for(j=0;j<group->unit_count;j++){
- unit2=&group->unit[j];
- if(unit1->bl.m==m && unit1->bl.x+dx==unit2->bl.x && unit1->bl.y+dy==unit2->bl.y){
- //ˆÚ“®æ‚Ƀ†ƒjƒbƒg‚ª‚©‚Ô‚Á‚Ä‚½‚ç
- s_flag[i]=1;// ˆÚ“®‘O‚̃†ƒjƒbƒgƒiƒ“ƒo?‚Ì?³ƒtƒ‰ƒOon
- r_flag[j]=1;// ‚©‚Ԃ郆ƒjƒbƒgƒiƒ“ƒo?‚Ì?—¯ƒtƒ‰ƒOon
- move_check=1;//ƒ†ƒjƒbƒg‚ª‚©‚Ô‚Á‚½B
- break;
- }
- }
- if(!move_check)// ƒ†ƒjƒbƒg‚ª‚©‚Ô‚Á‚ĂȂ©‚Á‚½‚ç
- m_flag[i]=1;// ˆÚ“®‘Oƒ†ƒjƒbƒgƒiƒ“ƒo?‚̈ړ®ƒtƒ‰ƒOon
- }
-
- //ƒtƒ‰ƒO‚ÉŠî‚¢‚ă†ƒjƒbƒgˆÚ“®
- for(i=0;i<group->unit_count;i++){
- unit1=&group->unit[i];
- if(m_flag[i]){// ˆÚ“®ƒtƒ‰ƒO‚ªon‚Å
- if(!r_flag[i]){// ?—¯ƒtƒ‰ƒO‚ªoff‚È‚ç
- //?ƒˆÚ“®(range‚à?³‚Ì•K—v–³‚µ)
- int range=unit1->range;
- map_delblock(&unit1->bl);
- unit1->bl.m = m;
- unit1->bl.x += dx;
- unit1->bl.y += dy;
- map_addblock(&unit1->bl);
- clif_skill_setunit(unit1);
- if(range > 0){
- if(range < 7)
- range = 7;
- map_foreachinarea( skill_unit_move_unit_group_sub, unit1->bl.m,
- unit1->bl.x-range,unit1->bl.y-range,unit1->bl.x+range,unit1->bl.y+range,0,
- &unit1->bl,gettick() );
- }
- }else{// ?—¯ƒtƒ‰ƒO‚ªon‚È‚ç
- //‹óƒ†ƒjƒbƒg‚ɂȂé‚Ì‚ÅA?³‰Â”\‚ȃ†ƒjƒbƒg‚ð’T‚·
- for(j=0;j<group->unit_count;j++){
- unit2=&group->unit[j];
- if(s_flag[j] && !r_flag[j]){
- // ?³ˆÚ“®(range?³•t‚«)
- int range=unit1->range;
- map_delblock(&unit2->bl);
- unit2->bl.m = m;
- unit2->bl.x = unit1->bl.x + dx;
- unit2->bl.y = unit1->bl.y + dy;
- unit2->range = unit1->range;
- map_addblock(&unit2->bl);
- clif_skill_setunit(unit2);
- if(range > 0){
- if(range < 7)
- range = 7;
- map_foreachinarea( skill_unit_move_unit_group_sub, unit2->bl.m,
- unit2->bl.x-range,unit2->bl.y-range,unit2->bl.x+range,unit2->bl.y+range,0,
- &unit2->bl,gettick() );
- }
- s_flag[j]=0;// ?³Š®—¹‚µ‚½‚Ì‚Åoff
- break;
- }
- }
- }
+ if (unit1->bl.x-dx==unit2->bl.x && unit1->bl.y-dy==unit2->bl.y){
+ // ƒ†ƒjƒbƒg‚ª‚±‚Ìꊂɂâ‚Á‚Ä‚­‚é
+ m_flag[i] |= 0x2;
+ }
+ }
+ }
+ // ƒtƒ‰ƒO‚ÉŠî‚¢‚ă†ƒjƒbƒgˆÚ“®
+ // ƒtƒ‰ƒO‚ª1‚Ìunit‚ð’T‚µAƒtƒ‰ƒO‚ª2‚Ìunit‚̈ړ®æ‚Ɉڂ·
+ j = 0;
+ for (i=0;i<group->unit_count;i++) {
+ unit1=&group->unit[i];
+ if (!unit1->alive)
+ continue;
+ if (!(m_flag[i]&0x2)) {
+ // ƒ†ƒjƒbƒg‚ª‚È‚­‚È‚éꊂŃXƒLƒ‹ƒ†ƒjƒbƒg‰e‹¿‚ðÁ‚·
+ map_foreachinarea(skill_unit_effect,unit1->bl.m,
+ unit1->bl.x,unit1->bl.y,unit1->bl.x,unit1->bl.y,0,
+ &unit1->bl,tick,0);
+ }
+ if (m_flag[i]==0) {
+ // ’PƒˆÚ“®
+ map_delblock(&unit1->bl);
+ unit1->bl.m = m;
+ unit1->bl.x += dx;
+ unit1->bl.y += dy;
+ map_addblock(&unit1->bl);
+ clif_skill_setunit(unit1);
+ } else if (m_flag[i]==1) {
+ // ƒtƒ‰ƒO‚ª2‚Ì‚à‚Ì‚ð’T‚µ‚Ä‚»‚̃†ƒjƒbƒg‚̈ړ®æ‚Ɉړ®
+ for(;j<group->unit_count;j++) {
+ if (m_flag[j]==2) {
+ // Œp³ˆÚ“®
+ unit2 = &group->unit[j];
+ if (!unit2->alive)
+ continue;
+ map_delblock(&unit1->bl);
+ unit1->bl.m = m;
+ unit1->bl.x = unit2->bl.x+dx;
+ unit1->bl.y = unit2->bl.y+dy;
+ map_addblock(&unit1->bl);
+ clif_skill_setunit(unit1);
+ j++;
+ break;
}
}
- free(r_flag);
- free(s_flag);
- free(m_flag);
+ }
+ if (!(m_flag[i]&0x2)) {
+ // ˆÚ“®Œã‚ÌꊂŃXƒLƒ‹ƒ†ƒjƒbƒg‚ð”­“®
+ map_foreachinarea(skill_unit_effect,unit1->bl.m,
+ unit1->bl.x,unit1->bl.y,unit1->bl.x,unit1->bl.y,0,
+ &unit1->bl,tick,1);
}
}
+ aFree(m_flag);
return 0;
}
@@ -10935,62 +8847,57 @@ int skill_produce_mix( struct map_session_data *sd,
/* Šm—¦”»’è */
equip = itemdb_isequip(nameid);
if(!equip) {
+// Corrected rates [DracoRPG] --------------------------//
if(skill_produce_db[idx].req_skill==AM_PHARMACY) {
- if((nameid >= 501 && nameid <= 506) || (nameid >= 545 && nameid <= 547) || nameid == 525)
- make_per = 2000 + sd->status.base_level*30 + sd->paramc[3]*20 + sd->paramc[4]*15 + pc_checkskill(sd,AM_LEARNINGPOTION)*100 + pc_checkskill(sd,AM_PHARMACY)*300 + pc_checkskill(sd,AM_POTIONPITCHER)*100;
- else if(nameid == 970)
- make_per = 1500 + sd->status.base_level*30 + sd->paramc[3]*20 + sd->paramc[4]*15 + pc_checkskill(sd,AM_LEARNINGPOTION)*100 + pc_checkskill(sd,AM_PHARMACY)*300;
- else if(nameid == 7135)
- make_per = 1000 + sd->status.base_level*30 + sd->paramc[3]*20 + sd->paramc[4]*15 + pc_checkskill(sd,AM_LEARNINGPOTION)*100 + pc_checkskill(sd,AM_PHARMACY)*300 + pc_checkskill(sd,AM_DEMONSTRATION)*100;
- else if(nameid == 7136)
- make_per = 1000 + sd->status.base_level*30 + sd->paramc[3]*20 + sd->paramc[4]*15 + pc_checkskill(sd,AM_LEARNINGPOTION)*100 + pc_checkskill(sd,AM_PHARMACY)*300 + pc_checkskill(sd,AM_ACIDTERROR)*100;
- else if(nameid == 7137)
- make_per = 1000 + sd->status.base_level*30 + sd->paramc[3]*20 + sd->paramc[4]*15 + pc_checkskill(sd,AM_LEARNINGPOTION)*100 + pc_checkskill(sd,AM_PHARMACY)*300 + pc_checkskill(sd,AM_CANNIBALIZE)*100;
- else if(nameid == 7138)
- make_per = 1000 + sd->status.base_level*30 + sd->paramc[3]*20 + sd->paramc[4]*15 + pc_checkskill(sd,AM_LEARNINGPOTION)*100 + pc_checkskill(sd,AM_PHARMACY)*300 + pc_checkskill(sd,AM_SPHEREMINE)*100;
- else if(nameid == 7139)
- make_per = 1000 + sd->status.base_level*30 + sd->paramc[3]*20 + sd->paramc[4]*15 + pc_checkskill(sd,AM_LEARNINGPOTION)*100 + pc_checkskill(sd,AM_PHARMACY)*300 + pc_checkskill(sd,AM_CP_WEAPON)*100 +
- pc_checkskill(sd,AM_CP_SHIELD)*100 + pc_checkskill(sd,AM_CP_ARMOR)*100 + pc_checkskill(sd,AM_CP_HELM)*100;
- else
- make_per = 1000 + sd->status.base_level*30 + sd->paramc[3]*20 + sd->paramc[4]*15 + pc_checkskill(sd,AM_LEARNINGPOTION)*100 + pc_checkskill(sd,AM_PHARMACY)*300;
+ make_per = pc_checkskill(sd,AM_LEARNINGPOTION)*100
+ + pc_checkskill(sd,AM_PHARMACY)*300 + sd->status.job_level*20
+ + sd->paramc[4]*10+sd->paramc[5]*10;
+
+ if(nameid >= 501 && nameid <= 505) // Normal potions
+ make_per += 2000 + pc_checkskill(sd,AM_POTIONPITCHER)*100;
+ else if(nameid >= 605 && nameid <= 606) // Anodyne & Aloevera (not sure of the formula, I put the same base value as normal pots but without the Aid Potion bonus since they are not throwable pots ^^)
+ make_per += 2000;
+ else if(nameid >= 545 && nameid <= 547) // Concentrated potions
+ ;
+ else if(nameid == 970) // Alcohol
+ make_per += 1000;
+ else if(nameid == 7135) // Bottle Grenade
+ make_per += 500 + pc_checkskill(sd,AM_DEMONSTRATION)*100;
+ else if(nameid == 7136) // Acid Bottle
+ make_per += 500 + pc_checkskill(sd,AM_ACIDTERROR)*100;
+ else if(nameid == 7137) // Plant Bottle
+ make_per += 500 + pc_checkskill(sd,AM_CANNIBALIZE)*100;
+ else if(nameid == 7138) // Marine Sphere Bottle
+ make_per += 500 + pc_checkskill(sd,AM_SPHEREMINE)*100;
+ else if(nameid == 7139) // Glistening Coat
+ make_per += 500 + pc_checkskill(sd,AM_CP_WEAPON)*100 + pc_checkskill(sd,AM_CP_SHIELD)*100 +
+ pc_checkskill(sd,AM_CP_ARMOR)*100 + pc_checkskill(sd,AM_CP_HELM)*100;
} else if (skill_produce_db[idx].req_skill == ASC_CDP) {
make_per = 2000 + 40*sd->paramc[4] + 20*sd->paramc[5];
- //make_per = 20 + (20*sd->paramc[4])/50 + (20*sd->paramc[5])/100;
} else {
if(nameid == 998)
- make_per = 2000 + sd->status.base_level*30 + sd->paramc[4]*20 + sd->paramc[5]*10 + pc_checkskill(sd,skill_produce_db[idx].req_skill)*600;
- else if(nameid == 985)
- make_per = 1000 + sd->status.base_level*30 + sd->paramc[4]*20 + sd->paramc[5]*10 + (pc_checkskill(sd,skill_produce_db[idx].req_skill)-1)*500;
+ make_per = 1500 + sd->status.job_level*35 + sd->paramc[4]*10 + sd->paramc[5]*10 + pc_checkskill(sd,skill_produce_db[idx].req_skill)*600;
else
- make_per = 1000 + sd->status.base_level*30 + sd->paramc[4]*20 + sd->paramc[5]*10 + pc_checkskill(sd,skill_produce_db[idx].req_skill)*500;
- }
- }
- else {
- int add_per;
- if(pc_search_inventory(sd,989) >= 0) add_per = 750;
- else if(pc_search_inventory(sd,988) >= 0) add_per = 500;
- else if(pc_search_inventory(sd,987) >= 0) add_per = 250;
- else if(pc_search_inventory(sd,986) >= 0) add_per = 0;
- else add_per = -500;
- if(ele) add_per -= 500;
- add_per -= sc*500;
+ make_per = 1000 + sd->status.job_level*35 + sd->paramc[4]*10 + sd->paramc[5]*10 + pc_checkskill(sd,skill_produce_db[idx].req_skill)*500;
+ }
+ if(battle_config.pp_rate != 100)
+ make_per = make_per * battle_config.pp_rate / 100;
+ } else { // Corrected rates [DracoRPG]
+ int add_per=0;
+ if(pc_search_inventory(sd,989) >= 0) add_per = 400;
+ else if(pc_search_inventory(sd,988) >= 0) add_per = 300;
+ else if(pc_search_inventory(sd,987) >= 0) add_per = 200;
+ else if(pc_search_inventory(sd,986) >= 0) add_per = 100;
wlv = itemdb_wlv(nameid);
- make_per = ((250 + sd->status.base_level*15 + sd->paramc[4]*10 + sd->paramc[5]*5 + pc_checkskill(sd,skill_produce_db[idx].req_skill)*500 +
- add_per) * (100 - (wlv - 1)*20))/100 + pc_checkskill(sd,BS_WEAPONRESEARCH)*100 + ((wlv >= 3)? pc_checkskill(sd,BS_ORIDEOCON)*100 : 0);
+ make_per = 1500 + sd->status.job_level*35 + sd->paramc[4]*10 + sd->paramc[5]*10 + pc_checkskill(sd,skill_produce_db[idx].req_skill)*1000 + pc_checkskill(sd,BS_WEAPONRESEARCH)*100 +
+ ((wlv >= 3)? pc_checkskill(sd,BS_ORIDEOCON)*100 : 0) + add_per - (ele? 2500:0) - sc*((4-wlv)*500) - wlv*1000;
+ if(battle_config.wp_rate != 100) /* Šm—¦•â³ */
+ make_per = make_per * battle_config.wp_rate / 100;
}
+// -----------------------------------------------------//
if(make_per < 1) make_per = 1;
- if(skill_produce_db[idx].req_skill==AM_PHARMACY ||
- skill_produce_db[idx].req_skill==ASC_CDP) {
- if( battle_config.pp_rate!=100 )
- make_per=make_per*battle_config.pp_rate/100;
- }
- else {
- if( battle_config.wp_rate!=100 ) /* Šm—¦•â³ */
- make_per=make_per*battle_config.wp_rate/100;
- }
-
// if(battle_config.etc_log)
// printf("make rate = %d\n",make_per);
@@ -11013,10 +8920,8 @@ int skill_produce_mix( struct map_session_data *sd,
*((unsigned long *)(&tmp_item.card[2]))=sd->char_id; /* ƒLƒƒƒ‰ID */
}
- #ifndef TXT_ONLY
if(log_config.produce > 0)
log_produce(sd,nameid,slot1,slot2,slot3,1);
- #endif //USE_SQL
switch (skill_produce_db[idx].req_skill) {
case AM_PHARMACY:
@@ -11037,12 +8942,9 @@ int skill_produce_mix( struct map_session_data *sd,
clif_additem(sd,0,0,flag);
map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0);
}
- }
- else {
- #ifndef TXT_ONLY
+ } else {
if(log_config.produce > 0)
log_produce(sd,nameid,slot1,slot2,slot3,0);
- #endif //USE_SQL
switch (skill_produce_db[idx].req_skill) {
case AM_PHARMACY:
@@ -11110,6 +9012,230 @@ int skill_arrow_create( struct map_session_data *sd,int nameid)
* ‰Šú‰»Œn
*/
+/*----------------------------------------------------------------------------
+ * ‰Šú‰»Œn
+ */
+
+/*
+ * •¶Žš—ñˆ—
+ * ',' ‚Å‹æØ‚Á‚Ä val ‚É–ß‚·
+ */
+int skill_split_str(char *str,char **val,int num)
+{
+ int i;
+
+ for (i=0; i<num && str; i++){
+ val[i] = str;
+ str = strchr(str,',');
+ if (str)
+ *str++=0;
+ }
+ return i;
+}
+/*
+ * •¶Žš—ñˆ—
+ * ':' ‚Å‹æØ‚Á‚Äatoi‚µ‚Äval‚É–ß‚·
+ */
+int skill_split_atoi(char *str,int *val)
+{
+ int i, max = 0;
+
+ for (i=0; i<MAX_SKILL_LEVEL; i++) {
+ if (str) {
+ val[i] = max = atoi(str);
+ str = strchr(str,':');
+ if (str)
+ *str++=0;
+ } else {
+ val[i] = max;
+ }
+ }
+ return i;
+}
+
+/*
+ * ƒXƒLƒ‹ƒ†ƒjƒbƒg‚Ì”z’uî•ñì¬
+ */
+void skill_init_unit_layout()
+{
+ int i,j,size,pos = 0;
+
+ memset(skill_unit_layout,0,sizeof(skill_unit_layout));
+ // ‹éŒ`‚̃†ƒjƒbƒg”z’u‚ð쬂·‚é
+ for (i=0; i<=MAX_SQUARE_LAYOUT; i++) {
+ size = i*2+1;
+ skill_unit_layout[i].count = size*size;
+ for (j=0; j<size*size; j++) {
+ skill_unit_layout[i].dx[j] = (j%size-i);
+ skill_unit_layout[i].dy[j] = (j/size-i);
+ }
+ }
+ pos = i;
+ // ‹éŒ`ˆÈŠO‚̃†ƒjƒbƒg”z’u‚ð쬂·‚é
+ for (i=0;i<MAX_SKILL_DB;i++) {
+ if (!skill_db[i].unit_id[0] || skill_db[i].unit_layout_type[0] != -1)
+ continue;
+ switch (i) {
+ case MG_FIREWALL:
+ case WZ_ICEWALL:
+ // ƒtƒ@ƒCƒA[ƒEƒH[ƒ‹AƒAƒCƒXƒEƒH[ƒ‹‚Í•ûŒü‚ŕςí‚é‚̂ŕʈ—
+ break;
+ case PR_SANCTUARY:
+ {
+ static const int dx[] = {
+ -1, 0, 1,-2,-1, 0, 1, 2,-2,-1,
+ 0, 1, 2,-2,-1, 0, 1, 2,-1, 0, 1};
+ static const int dy[]={
+ -2,-2,-2,-1,-1,-1,-1,-1, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2};
+ skill_unit_layout[pos].count = 21;
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ break;
+ }
+ case PR_MAGNUS:
+ {
+ static const int dx[] = {
+ -1, 0, 1,-1, 0, 1,-3,-2,-1, 0,
+ 1, 2, 3,-3,-2,-1, 0, 1, 2, 3,
+ -3,-2,-1, 0, 1, 2, 3,-1, 0, 1,-1, 0, 1};
+ static const int dy[] = {
+ -3,-3,-3,-2,-2,-2,-1,-1,-1,-1,
+ -1,-1,-1, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3};
+ skill_unit_layout[pos].count = 33;
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ break;
+ }
+ case AS_VENOMDUST:
+ {
+ static const int dx[] = {-1, 0, 0, 0, 1};
+ static const int dy[] = { 0,-1, 0, 1, 0};
+ skill_unit_layout[pos].count = 5;
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ break;
+ }
+ case CR_GRANDCROSS:
+ case NPC_DARKGRANDCROSS:
+ {
+ static const int dx[] = {
+ 0, 0,-1, 0, 1,-2,-1, 0, 1, 2,
+ -4,-3,-2,-1, 0, 1, 2, 3, 4,-2,
+ -1, 0, 1, 2,-1, 0, 1, 0, 0};
+ static const int dy[] = {
+ -4,-3,-2,-2,-2,-1,-1,-1,-1,-1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 1, 1, 1, 1, 2, 2, 2, 3, 4};
+ skill_unit_layout[pos].count = 29;
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ break;
+ }
+ case PF_FOGWALL:
+ {
+ static const int dx[] = {
+ -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2};
+ static const int dy[] = {
+ -1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};
+ skill_unit_layout[pos].count = 15;
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ break;
+ }
+ case PA_GOSPEL:
+ {
+ static const int dx[] = {
+ -1, 0, 1,-1, 0, 1,-3,-2,-1, 0,
+ 1, 2, 3,-3,-2,-1, 0, 1, 2, 3,
+ -3,-2,-1, 0, 1, 2, 3,-1, 0, 1,
+ -1, 0, 1};
+ static const int dy[] = {
+ -3,-3,-3,-2,-2,-2,-1,-1,-1,-1,
+ -1,-1,-1, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
+ 3, 3, 3};
+ skill_unit_layout[pos].count = 33;
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ break;
+ }
+ default:
+ printf("unknown unit layout at skill %d\n",i);
+ break;
+ }
+ if (!skill_unit_layout[pos].count)
+ continue;
+ for (j=0;j<MAX_SKILL_LEVEL;j++)
+ skill_db[i].unit_layout_type[j] = pos;
+ pos++;
+ }
+ // ƒtƒ@ƒCƒ„[ƒEƒH[ƒ‹
+ firewall_unit_pos = pos;
+ for (i=0;i<8;i++) {
+ if (i&1) { /* ŽÎ‚ß”z’u */
+ skill_unit_layout[pos].count = 5;
+ if (i&0x2) {
+ int dx[] = {-1,-1, 0, 0, 1};
+ int dy[] = { 1, 0, 0,-1,-1};
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ } else {
+ int dx[] = { 1, 1 ,0, 0,-1};
+ int dy[] = { 1, 0, 0,-1,-1};
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ }
+ } else { /* c‰¡”z’u */
+ skill_unit_layout[pos].count = 3;
+ if (i%4==0) { /* ㉺ */
+ int dx[] = {-1, 0, 1};
+ int dy[] = { 0, 0, 0};
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ } else { /* ¶‰E */
+ int dx[] = { 0, 0, 0};
+ int dy[] = {-1, 0, 1};
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ }
+ }
+ pos++;
+ }
+ // ƒAƒCƒXƒEƒH[ƒ‹
+ icewall_unit_pos = pos;
+ for (i=0;i<8;i++) {
+ skill_unit_layout[pos].count = 5;
+ if (i&1) { /* ŽÎ‚ß”z’u */
+ if (i&0x2) {
+ int dx[] = {-2,-1, 0, 1, 2};
+ int dy[] = { 2,-1, 0,-1,-2};
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ } else {
+ int dx[] = { 2, 1 ,0,-1,-2};
+ int dy[] = { 2, 1, 0,-1,-2};
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ }
+ } else { /* c‰¡”z’u */
+ if (i%4==0) { /* ㉺ */
+ int dx[] = {-2,-1, 0, 1, 2};
+ int dy[] = { 0, 0, 0, 0, 0};
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ } else { /* ¶‰E */
+ int dx[] = { 0, 0, 0, 0, 0};
+ int dy[] = {-2,-1, 0, 1, 2};
+ memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
+ }
+ }
+ pos++;
+ }
+}
+
/*==========================================
* ƒXƒLƒ‹?ŒWƒtƒ@ƒCƒ‹?‚Ý?‚Ý
* skill_db.txt ƒXƒLƒ‹ƒf?ƒ^
@@ -11134,46 +9260,27 @@ int skill_readdb(void)
return 1;
}
while(fgets(line,1020,fp)){
- char *split[50], *split2[MAX_SKILL_LEVEL];
+ char *split[50];
if(line[0]=='/' && line[1]=='/')
continue;
- for(j=0,p=line;j<14 && p;j++){
- split[j]=p;
- p=strchr(p,',');
- if(p) *p++=0;
- }
+ j = skill_split_str(line,split,14);
if(split[13]==NULL || j<14)
continue;
i=atoi(split[0]);
if (i>=10000 && i<10015) // for guild skills [Celest]
i -= 9500;
- else if(i<0 || i>MAX_SKILL_DB)
+ else if(i<=0 || i>MAX_SKILL_DB)
continue;
/* printf("skill id=%d\n",i); */
- memset(split2,0,sizeof(split2));
- for(j=0,p=split[1];j<MAX_SKILL_LEVEL && p;j++){
- split2[j]=p;
- p=strchr(p,':');
- if(p) *p++=0;
- }
- for(k=0;k<MAX_SKILL_LEVEL;k++)
- skill_db[i].range[k]=(split2[k])? atoi(split2[k]):atoi(split2[0]);
+ skill_split_atoi(split[1],skill_db[i].range);
skill_db[i].hit=atoi(split[2]);
skill_db[i].inf=atoi(split[3]);
skill_db[i].pl=atoi(split[4]);
skill_db[i].nk=atoi(split[5]);
skill_db[i].max=atoi(split[6]);
-
- memset(split2,0,sizeof(split2));
- for(j=0,p=split[7];j<MAX_SKILL_LEVEL && p;j++){
- split2[j]=p;
- p=strchr(p,':');
- if(p) *p++=0;
- }
- for(k=0;k<MAX_SKILL_LEVEL;k++)
- skill_db[i].num[k]=(split2[k])? atoi(split2[k]):atoi(split2[0]);
+ skill_split_atoi(split[7],skill_db[i].num);
if(strcmpi(split[8],"yes") == 0)
skill_db[i].castcancel=1;
@@ -11190,17 +9297,11 @@ int skill_readdb(void)
skill_db[i].skill_type=BF_MISC;
else
skill_db[i].skill_type=0;
- memset(split2,0,sizeof(split2));
- for(j=0,p=split[13];j<MAX_SKILL_LEVEL && p;j++){
- split2[j]=p;
- p=strchr(p,':');
- if(p) *p++=0;
- }
- for(k=0;k<MAX_SKILL_LEVEL;k++)
- skill_db[i].blewcount[k]=(split2[k])? atoi(split2[k]):atoi(split2[0]);
+ skill_split_atoi(split[13],skill_db[i].blewcount);
}
fclose(fp);
- printf("read db/skill_db.txt done\n");
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/skill_db.txt");
+ ShowStatus(tmp_output);
fp=fopen("db/skill_require_db.txt","r");
if(fp==NULL){
@@ -11208,91 +9309,39 @@ int skill_readdb(void)
return 1;
}
while(fgets(line,1020,fp)){
- char *split[51], *split2[MAX_SKILL_LEVEL];
+ char *split[50];
if(line[0]=='/' && line[1]=='/')
continue;
- for(j=0,p=line;j<30 && p;j++){
- split[j]=p;
- p=strchr(p,',');
- if(p) *p++=0;
- }
+ j = skill_split_str(line,split,30);
if(split[29]==NULL || j<30)
continue;
i=atoi(split[0]);
if (i>=10000 && i<10015) // for guild skills [Celest]
i -= 9500;
- else if(i<0 || i>MAX_SKILL_DB)
+ else if(i<=0 || i>MAX_SKILL_DB)
continue;
- memset(split2,0,sizeof(split2));
- for(j=0,p=split[1];j<MAX_SKILL_LEVEL && p;j++){
- split2[j]=p;
- p=strchr(p,':');
- if(p) *p++=0;
- }
- for(k=0;k<MAX_SKILL_LEVEL;k++)
- skill_db[i].hp[k]=(split2[k])? atoi(split2[k]):atoi(split2[0]);
-
- memset(split2,0,sizeof(split2));
- for(j=0,p=split[2];j<MAX_SKILL_LEVEL && p;j++){
- split2[j]=p;
- p=strchr(p,':');
- if(p) *p++=0;
- }
- for(k=0;k<MAX_SKILL_LEVEL;k++)
- skill_db[i].mhp[k]=(split2[k])? atoi(split2[k]):atoi(split2[0]);
-
- memset(split2,0,sizeof(split2));
- for(j=0,p=split[3];j<MAX_SKILL_LEVEL && p;j++){
- split2[j]=p;
- p=strchr(p,':');
- if(p) *p++=0;
- }
- for(k=0;k<MAX_SKILL_LEVEL;k++)
- skill_db[i].sp[k]=(split2[k])? atoi(split2[k]):atoi(split2[0]);
-
- memset(split2,0,sizeof(split2));
- for(j=0,p=split[4];j<MAX_SKILL_LEVEL && p;j++){
- split2[j]=p;
- p=strchr(p,':');
- if(p) *p++=0;
- }
- for(k=0;k<MAX_SKILL_LEVEL;k++)
- skill_db[i].hp_rate[k]=(split2[k])? atoi(split2[k]):atoi(split2[0]);
-
- memset(split2,0,sizeof(split2));
- for(j=0,p=split[5];j<MAX_SKILL_LEVEL && p;j++){
- split2[j]=p;
- p=strchr(p,':');
- if(p) *p++=0;
- }
- for(k=0;k<MAX_SKILL_LEVEL;k++)
- skill_db[i].sp_rate[k]=(split2[k])? atoi(split2[k]):atoi(split2[0]);
-
- memset(split2,0,sizeof(split2));
- for(j=0,p=split[6];j<MAX_SKILL_LEVEL && p;j++){
- split2[j]=p;
- p=strchr(p,':');
- if(p) *p++=0;
- }
- for(k=0;k<MAX_SKILL_LEVEL;k++)
- skill_db[i].zeny[k]=(split2[k])? atoi(split2[k]):atoi(split2[0]);
-
- memset(split2,0,sizeof(split2));
- for(j=0,p=split[7];j<32 && p;j++){
- split2[j]=p;
- p=strchr(p,':');
- if(p) *p++=0;
- }
- for(k=0;k<32 && split2[k];k++) {
- l = atoi(split2[k]);
- if(l == 99) {
+ skill_split_atoi(split[1],skill_db[i].hp);
+ skill_split_atoi(split[2],skill_db[i].mhp);
+ skill_split_atoi(split[3],skill_db[i].sp);
+ skill_split_atoi(split[4],skill_db[i].hp_rate);
+ skill_split_atoi(split[5],skill_db[i].sp_rate);
+ skill_split_atoi(split[6],skill_db[i].zeny);
+
+ p = split[7];
+ for(j=0;j<32;j++){
+ l = atoi(p);
+ if (l==99) {
skill_db[i].weapon = 0xffffffff;
break;
}
else
skill_db[i].weapon |= 1<<l;
+ p=strchr(p,':');
+ if(!p)
+ break;
+ p++;
}
if( strcmpi(split[8],"hiding")==0 ) skill_db[i].state=ST_HIDING;
@@ -11309,14 +9358,7 @@ int skill_readdb(void)
else if( strcmpi(split[8],"water")==0 ) skill_db[i].state=ST_WATER;
else skill_db[i].state=ST_NONE;
- memset(split2,0,sizeof(split2));
- for(j=0,p=split[9];j<MAX_SKILL_LEVEL && p;j++){
- split2[j]=p;
- p=strchr(p,':');
- if(p) *p++=0;
- }
- for(k=0;k<MAX_SKILL_LEVEL;k++)
- skill_db[i].spiritball[k]=(split2[k])? atoi(split2[k]):atoi(split2[0]);
+ skill_split_atoi(split[9],skill_db[i].spiritball);
skill_db[i].itemid[0]=atoi(split[10]);
skill_db[i].amount[0]=atoi(split[11]);
skill_db[i].itemid[1]=atoi(split[12]);
@@ -11339,7 +9381,8 @@ int skill_readdb(void)
skill_db[i].amount[9]=atoi(split[29]);
}
fclose(fp);
- printf("read db/skill_require_db.txt done\n");
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/skill_require_db.txt");
+ ShowStatus(tmp_output);
/* ƒLƒƒƒXƒeƒBƒ“ƒOƒf?ƒ^ƒx?ƒX */
fp=fopen("db/skill_cast_db.txt","r");
@@ -11348,62 +9391,70 @@ int skill_readdb(void)
return 1;
}
while(fgets(line,1020,fp)){
- char *split[50], *split2[MAX_SKILL_LEVEL];
+ char *split[50];
memset(split,0,sizeof(split)); // [Valaris] thanks to fov
if(line[0]=='/' && line[1]=='/')
continue;
- for(j=0,p=line;j<5 && p;j++){
- split[j]=p;
- p=strchr(p,',');
- if(p) *p++=0;
- }
+ j = skill_split_str(line,split,5);
if(split[4]==NULL || j<5)
continue;
i=atoi(split[0]);
if (i>=10000 && i<10015) // for guild skills [Celest]
i -= 9500;
- else if(i<0 || i>MAX_SKILL_DB)
+ else if(i<=0 || i>MAX_SKILL_DB)
continue;
- memset(split2,0,sizeof(split2));
- for(j=0,p=split[1];j<MAX_SKILL_LEVEL && p;j++){
- split2[j]=p;
- p=strchr(p,':');
- if(p) *p++=0;
- }
- for(k=0;k<MAX_SKILL_LEVEL;k++)
- skill_db[i].cast[k]=(split2[k])? atoi(split2[k]):atoi(split2[0]);
-
- memset(split2,0,sizeof(split2));
- for(j=0,p=split[2];j<MAX_SKILL_LEVEL && p;j++){
- split2[j]=p;
- p=strchr(p,':');
- if(p) *p++=0;
- }
- for(k=0;k<MAX_SKILL_LEVEL;k++)
- skill_db[i].delay[k]=(split2[k])? atoi(split2[k]):atoi(split2[0]);
+ skill_split_atoi(split[1],skill_db[i].cast);
+ skill_split_atoi(split[2],skill_db[i].delay);
+ skill_split_atoi(split[3],skill_db[i].upkeep_time);
+ skill_split_atoi(split[4],skill_db[i].upkeep_time2);
+ }
+ fclose(fp);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/skill_cast_db.txt");
+ ShowStatus(tmp_output);
- memset(split2,0,sizeof(split2));
- for(j=0,p=split[3];j<MAX_SKILL_LEVEL && p;j++){
- split2[j]=p;
- p=strchr(p,':');
- if(p) *p++=0;
- }
- for(k=0;k<MAX_SKILL_LEVEL;k++)
- skill_db[i].upkeep_time[k]=(split2[k])? atoi(split2[k]):atoi(split2[0]);
+ /* ƒXƒLƒ‹ƒ†ƒjƒbƒgƒf[ƒ^ƒx[ƒX */
+ fp = fopen("db/skill_unit_db.txt","r");
+ if (fp==NULL) {
+ printf("can't read db/skill_unit_db.txt\n");
+ return 1;
+ }
+ k = 0;
+ while (fgets(line,1020,fp)) {
+ char *split[50];
+ if (line[0]=='/' && line[1]=='/')
+ continue;
+ j = skill_split_str(line,split,8);
+ if (split[7]==NULL || j<8)
+ continue;
- memset(split2,0,sizeof(split2));
- for(j=0,p=split[4];j<MAX_SKILL_LEVEL && p;j++){
- split2[j]=p;
- p=strchr(p,':');
- if(p) *p++=0;
- }
- for(k=0;k<MAX_SKILL_LEVEL;k++)
- skill_db[i].upkeep_time2[k]=(split2[k])? atoi(split2[k]):atoi(split2[0]);
+ i=atoi(split[0]);
+ if (i>=10000 && i<10015) // for guild skills [Celest]
+ i -= 9500;
+ else if(i<=0 || i>MAX_SKILL_DB)
+ continue;
+ skill_db[i].unit_id[0] = strtol(split[1],NULL,16);
+ skill_db[i].unit_id[1] = strtol(split[2],NULL,16);
+ skill_split_atoi(split[3],skill_db[i].unit_layout_type);
+ skill_db[i].unit_range = atoi(split[4]);
+ skill_db[i].unit_interval = atoi(split[5]);
+
+ if( strcmpi(split[6],"noenemy")==0 ) skill_db[i].unit_target=BCT_NOENEMY;
+ else if( strcmpi(split[6],"friend")==0 ) skill_db[i].unit_target=BCT_NOENEMY;
+ else if( strcmpi(split[6],"party")==0 ) skill_db[i].unit_target=BCT_PARTY;
+ else if( strcmpi(split[6],"all")==0 ) skill_db[i].unit_target=BCT_ALL;
+ else if( strcmpi(split[6],"enemy")==0 ) skill_db[i].unit_target=BCT_ENEMY;
+ else if( strcmpi(split[6],"self")==0 ) skill_db[i].unit_target=BCT_SELF;
+ else skill_db[i].unit_target = strtol(split[6],NULL,16);
+
+ skill_db[i].unit_flag = strtol(split[7],NULL,16);
+ k++;
}
fclose(fp);
- printf("read db/skill_cast_db.txt done\n");
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/skill_unit_db.txt");
+ ShowStatus(tmp_output);
+ skill_init_unit_layout();
/* »‘¢ŒnƒXƒLƒ‹ƒf?ƒ^ƒx?ƒX */
memset(skill_produce_db,0,sizeof(skill_produce_db));
@@ -11422,16 +9473,11 @@ int skill_readdb(void)
if(line[0]=='/' && line[1]=='/')
continue;
memset(split,0,sizeof(split));
- for(j=0,p=line;j<3 + MAX_PRODUCE_RESOURCE * 2 && p;j++){
- split[j]=p;
- p=strchr(p,',');
- if(p) *p++=0;
- }
- if(split[0]==NULL)
+ j = skill_split_str(line,split,(3 + MAX_PRODUCE_RESOURCE * 2));
+ if(split[0]==0) //fixed by Lupus
continue;
i=atoi(split[0]);
- if(i<=0)
- continue;
+ if(i<=0) continue;
skill_produce_db[k].nameid=i;
skill_produce_db[k].itemlv=atoi(split[1]);
@@ -11446,7 +9492,8 @@ int skill_readdb(void)
break;
}
fclose(fp);
- printf("read %s done (count=%d)\n",filename[m],k);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",k,filename[m]);
+ ShowStatus(tmp_output);
}
memset(skill_arrow_db,0,sizeof(skill_arrow_db));
@@ -11462,12 +9509,8 @@ int skill_readdb(void)
if(line[0]=='/' && line[1]=='/')
continue;
memset(split,0,sizeof(split));
- for(j=0,p=line;j<13 && p;j++){
- split[j]=p;
- p=strchr(p,',');
- if(p) *p++=0;
- }
- if(split[0]==NULL)
+ j = skill_split_str(line,split,13);
+ if(split[0]==0) //fixed by Lupus
continue;
i=atoi(split[0]);
if(i<=0)
@@ -11484,7 +9527,8 @@ int skill_readdb(void)
break;
}
fclose(fp);
- printf("read db/create_arrow_db.txt done (count=%d)\n",k);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",k,"db/create_arrow_db.txt");
+ ShowStatus(tmp_output);
memset(skill_abra_db,0,sizeof(skill_abra_db));
fp=fopen("db/abra_db.txt","r");
@@ -11498,12 +9542,8 @@ int skill_readdb(void)
if(line[0]=='/' && line[1]=='/')
continue;
memset(split,0,sizeof(split));
- for(j=0,p=line;j<13 && p;j++){
- split[j]=p;
- p=strchr(p,',');
- if(p) *p++=0;
- }
- if(split[0]==NULL)
+ j = skill_split_str(line,split,13);
+ if(split[0]==0) //fixed by Lupus
continue;
i=atoi(split[0]);
if(i<=0)
@@ -11517,7 +9557,8 @@ int skill_readdb(void)
break;
}
fclose(fp);
- printf("read db/abra_db.txt done (count=%d)\n",k);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",k,"db/abra_db.txt");
+ ShowStatus(tmp_output);
fp=fopen("db/skill_castnodex_db.txt","r");
if(fp==NULL){
@@ -11525,33 +9566,27 @@ int skill_readdb(void)
return 1;
}
while(fgets(line,1020,fp)){
- char *split[50], *split2[MAX_SKILL_LEVEL];
- memset(split,0,sizeof(split));
+ char *split[50];
if(line[0]=='/' && line[1]=='/')
continue;
- for(j=0,p=line;j<2 && p;j++){
- split[j]=p;
- p=strchr(p,',');
- if(p) *p++=0;
- }
-
+ memset(split,0,sizeof(split));
+ j = skill_split_str(line,split,3);
+ if(split[0]==0) //fixed by Lupus
+ continue;
i=atoi(split[0]);
if (i>=10000 && i<10015) // for guild skills [Celest]
i -= 9500;
- else if(i<0 || i>MAX_SKILL_DB)
+ else if(i<=0 || i>MAX_SKILL_DB)
continue;
- memset(split2,0,sizeof(split2));
- for(j=0,p=split[1];j<MAX_SKILL_LEVEL && p;j++){
- split2[j]=p;
- p=strchr(p,':');
- if(p) *p++=0;
- }
- for(k=0;k<MAX_SKILL_LEVEL;k++)
- skill_db[i].castnodex[k]=(split2[k])? atoi(split2[k]):atoi(split2[0]);
+ skill_split_atoi(split[1],skill_db[i].castnodex);
+ if (!split[2])
+ continue;
+ skill_split_atoi(split[2],skill_db[i].delaynodex);
}
fclose(fp);
- printf("read db/skill_castnodex_db.txt done\n");
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/skill_castnodex_db.txt");
+ ShowStatus(tmp_output);
fp=fopen("db/skill_nocast_db.txt","r");
if(fp==NULL){
@@ -11564,35 +9599,75 @@ int skill_readdb(void)
if(line[0]=='/' && line[1]=='/')
continue;
memset(split,0,sizeof(split));
- for(j=0,p=line;j<2 && p;j++){
- split[j]=p;
- p=strchr(p,',');
- if(p) *p++=0;
- }
- if(split[0]==NULL)
+ j = skill_split_str(line,split,2);
+ if(split[0]==0) //fixed by Lupus
continue;
i=atoi(split[0]);
- if(i < 0 || i > MAX_SKILL_DB)
+ if (i>=10000 && i<10015) // for guild skills [Celest]
+ i -= 9500;
+ else if(i<=0 || i>MAX_SKILL_DB)
continue;
skill_db[i].nocast=atoi(split[1]);
k++;
}
fclose(fp);
- printf("read db/skill_nocast_db done\n");
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/skill_nocast_db");
+ ShowStatus(tmp_output);
return 0;
}
-void skill_reload(void)
+/*===============================================
+ * For reading leveluseskillspamount.txt [Celest]
+ *-----------------------------------------------
+ */
+static int skill_read_skillspamount(void)
{
- /*
+ char *buf,*p;
+ struct skill_db *skill = NULL;
+ int s, idx, new_flag=1, level=1, sp=0;
+
+ buf=(char *) grfio_reads("data\\leveluseskillspamount.txt",&s);
+
+ if(buf==NULL)
+ return -1;
+
+ buf[s]=0;
+ for(p=buf;p-buf<s;){
+ char buf2[64];
+
+ if (sscanf(p,"%[@]",buf2) == 1) {
+ level = 1;
+ new_flag = 1;
+ } else if (new_flag && sscanf(p,"%[^#]#",buf2) == 1) {
+ for (idx=0; skill_names[idx].id != 0; idx++) {
+ if (strstr(buf2, skill_names[idx].name) != NULL) {
+ skill = &skill_db[ skill_names[idx].id ];
+ new_flag = 0;
+ break;
+ }
+ }
+ } else if (!new_flag && sscanf(p,"%d#",&sp) == 1) {
+ skill->sp[level-1]=sp;
+ level++;
+ }
- <empty skill database>
- <?>
+ p=strchr(p,10);
+ if(!p) break;
+ p++;
+ }
+ aFree(buf);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","data\\leveluseskillspamount.txt");
+ ShowStatus(tmp_output);
- */
+ return 0;
+}
- do_init_skill();
+void skill_reload(void)
+{
+ skill_readdb();
+ if (battle_config.skill_sp_override_grffile)
+ skill_read_skillspamount();
}
/*==========================================
@@ -11602,12 +9677,13 @@ void skill_reload(void)
int do_init_skill(void)
{
skill_readdb();
+ if (battle_config.skill_sp_override_grffile)
+ skill_read_skillspamount();
add_timer_func_list(skill_unit_timer,"skill_unit_timer");
add_timer_func_list(skill_castend_id,"skill_castend_id");
add_timer_func_list(skill_castend_pos,"skill_castend_pos");
add_timer_func_list(skill_timerskill,"skill_timerskill");
- add_timer_func_list(skill_status_change_timer,"skill_status_change_timer");
add_timer_interval(gettick()+SKILLUNITTIMER_INVERVAL,skill_unit_timer,0,0,SKILLUNITTIMER_INVERVAL);
return 0;
diff --git a/src/map/skill.h b/src/map/skill.h
index a8bf30e3c..67d7a906c 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -1,10 +1,10 @@
-// $Id: skill.h,v 1.5 2004/11/26 5:47:12 PM Celestia Exp $
+// $Id: skill.h,v 1.5 2004/12/23 7:43:16 PM Celestia $
#ifndef _SKILL_H_
#define _SKILL_H_
#include "map.h"
-#define MAX_SKILL_DB 515
+#define MAX_SKILL_DB 750
#define MAX_SKILL_PRODUCE_DB 150
#define MAX_PRODUCE_RESOURCE 7
#define MAX_SKILL_ARROW_DB 150
@@ -23,7 +23,14 @@ struct skill_db {
int weapon,state,spiritball[MAX_SKILL_LEVEL];
int itemid[10],amount[10];
int castnodex[MAX_SKILL_LEVEL];
+ int delaynodex[MAX_SKILL_LEVEL];
int nocast;
+ int unit_id[2];
+ int unit_layout_type[MAX_SKILL_LEVEL];
+ int unit_range;
+ int unit_interval;
+ int unit_target;
+ int unit_flag;
};
extern struct skill_db skill_db[MAX_SKILL_DB];
@@ -34,6 +41,24 @@ struct skill_name_db {
};
extern const struct skill_name_db skill_names[];
+#define MAX_SKILL_UNIT_LAYOUT 50
+#define MAX_SQUARE_LAYOUT 5 // 11*11‚̃†ƒjƒbƒg”z’u‚ªÅ‘å
+#define MAX_SKILL_UNIT_COUNT ((MAX_SQUARE_LAYOUT*2+1)*(MAX_SQUARE_LAYOUT*2+1))
+struct skill_unit_layout {
+ int count;
+ int dx[MAX_SKILL_UNIT_COUNT];
+ int dy[MAX_SKILL_UNIT_COUNT];
+};
+
+enum {
+ UF_DEFNOTENEMY = 0x0001, // defnotenemy Ý’è‚ÅBCT_NOENEMY‚ÉØ‚è‘Ö‚¦
+ UF_NOREITERATION = 0x0002, // d•¡’u‚«‹ÖŽ~
+ UF_NOFOOTSET = 0x0004, // ‘«Œ³’u‚«‹ÖŽ~
+ UF_NOOVERLAP = 0x0008, // ƒ†ƒjƒbƒgŒø‰Ê‚ªd•¡‚µ‚È‚¢
+ UF_DANCE = 0x0100, // ƒ_ƒ“ƒXƒXƒLƒ‹
+ UF_ENSEMBLE = 0x0200, // ‡‘tƒXƒLƒ‹
+};
+
// ƒAƒCƒeƒ€ì¬ƒf?ƒ^ƒx?ƒX
struct skill_produce_db {
int nameid, trigger;
@@ -57,6 +82,9 @@ struct skill_abra_db {
};
extern struct skill_abra_db skill_abra_db[MAX_SKILL_ABRA_DB];
+extern int enchant_eff[5];
+extern int deluge_eff[5];
+
struct block_list;
struct map_session_data;
struct skill_unit;
@@ -86,6 +114,7 @@ int skill_get_unit_id(int id,int flag);
int skill_get_inf2( int id );
int skill_get_maxcount( int id );
int skill_get_blewcount( int id ,int lv );
+int skill_get_unit_flag( int id );
int skill_tree_get_max( int id, int b_class ); // Celest
// ƒXƒLƒ‹‚ÌŽg—p
@@ -109,9 +138,6 @@ int skill_delunit(struct skill_unit *unit);
struct skill_unit_group *skill_initunitgroup(struct block_list *src,
int count,int skillid,int skilllv,int unit_id);
int skill_delunitgroup(struct skill_unit_group *group);
-struct skill_unit_group_tickset *skill_unitgrouptickset_search(
- struct block_list *bl,int group_id);
-int skill_unitgrouptickset_delete(struct block_list *bl,int group_id);
int skill_clear_unitgroup(struct block_list *src);
int skill_unit_ondamaged(struct skill_unit *src,struct block_list *bl,
@@ -119,21 +145,25 @@ int skill_unit_ondamaged(struct skill_unit *src,struct block_list *bl,
int skill_castfix( struct block_list *bl, int time );
int skill_delayfix( struct block_list *bl, int time );
-int skill_check_unit_range(int m,int x,int y,int range,int skillid);
-int skill_check_unit_range2(int m,int x,int y,int range);
+int skill_check_unit_range(int m,int x,int y,int skillid, int skilllv);
+int skill_check_unit_range2(struct block_list *bl,int m,int x,int y,int skillid, int skilllv);
// -- moonsoul (added skill_check_unit_cell)
int skill_check_unit_cell(int skillid,int m,int x,int y,int unit_id);
int skill_unit_out_all( struct block_list *bl,unsigned int tick,int range);
-int skill_unit_move( struct block_list *bl,unsigned int tick,int range);
+int skill_unit_move(struct block_list *bl,unsigned int tick,int flag);
int skill_unit_move_unit_group( struct skill_unit_group *group, int m,int dx,int dy);
struct skill_unit_group *skill_check_dancing( struct block_list *src );
void skill_stop_dancing(struct block_list *src, int flag);
+// Guild skills [celest]
+int skill_guildaura_sub (struct block_list *bl,va_list ap);
+
// ‰r¥ƒLƒƒƒ“ƒZƒ‹
int skill_castcancel(struct block_list *bl,int type);
int skill_gangsterparadise(struct map_session_data *sd ,int type);
+int skill_check_moonlit (struct block_list *bl, int dx, int dy);
void skill_brandishspear_first(struct square *tc,int dir,int x,int y);
void skill_brandishspear_dir(struct square *tc,int dir,int are);
int skill_autospell(struct map_session_data *md,int skillid);
@@ -142,19 +172,13 @@ void skill_devotion2(struct block_list *bl,int crusader);
int skill_devotion3(struct block_list *bl,int target);
void skill_devotion_end(struct map_session_data *md,struct map_session_data *sd,int target);
-#define skill_calc_heal(bl,skill_lv) (( battle_get_lv(bl)+battle_get_int(bl) )/8 *(4+ skill_lv*8))
+#define skill_calc_heal(bl,skill_lv) (( status_get_lv(bl)+status_get_int(bl) )/8 *(4+ skill_lv*8))
// ‚»‚Ì‘¼
int skill_check_cloaking(struct block_list *bl);
-int skill_type_cloaking(struct block_list *bl);
-int skill_is_danceskill(int id);
// ƒXƒe?ƒ^ƒXˆÙí
-int skill_status_change_start(struct block_list *bl,int type,int val1,int val2,int val3,int val4,int tick,int flag);
-int skill_status_change_timer(int tid, unsigned int tick, int id, int data);
-int skill_encchant_eremental_end(struct block_list *bl, int type);
-int skill_status_change_end( struct block_list* bl , int type,int tid );
-int skill_status_change_clear(struct block_list *bl,int type);
+int skill_enchant_elemental_end(struct block_list *bl, int type);
int skillnotok(int skillid, struct map_session_data *sd);
// ƒAƒCƒeƒ€ì¬
@@ -180,201 +204,6 @@ enum {
ST_RECOV_WEIGHT_RATE,ST_MOVE_ENABLE,ST_WATER,
};
-enum { // struct map_session_data ‚Ì status_change‚Ì”Ô?ƒe?ƒuƒ‹
-// SC_SENDMAX–¢?‚̓Nƒ‰ƒCƒAƒ“ƒg‚Ö‚Ì’Ê’m‚ ‚èB
-// 2-2ŽŸE‚Ì’l‚͂Ȃñ‚©‚ß‚¿‚á‚­‚¿‚á‚Á‚Û‚¢‚̂Ŏb’èB‚½‚Ô‚ñ?X‚³‚ê‚Ü‚·B
- SC_SENDMAX =128,
- SC_PROVOKE = 0,
- SC_ENDURE = 1,
- SC_TWOHANDQUICKEN = 2,
- SC_CONCENTRATE = 3,
- SC_HIDING = 4,
- SC_CLOAKING = 5,
- SC_ENCPOISON = 6,
- SC_POISONREACT = 7,
- SC_QUAGMIRE = 8,
- SC_ANGELUS = 9,
- SC_BLESSING =10,
- SC_SIGNUMCRUCIS =11,
- SC_INCREASEAGI =12,
- SC_DECREASEAGI =13,
- SC_SLOWPOISON =14,
- SC_IMPOSITIO =15,
- SC_SUFFRAGIUM =16,
- SC_ASPERSIO =17,
- SC_BENEDICTIO =18,
- SC_KYRIE =19,
- SC_MAGNIFICAT =20,
- SC_GLORIA =21,
- SC_AETERNA =22,
- SC_ADRENALINE =23,
- SC_WEAPONPERFECTION =24,
- SC_OVERTHRUST =25,
- SC_MAXIMIZEPOWER =26,
- SC_RIDING =27,
- SC_FALCON =28,
- SC_TRICKDEAD =29,
- SC_LOUD =30,
- SC_ENERGYCOAT =31,
- SC_HALLUCINATION =34,
- SC_WEIGHT50 =35,
- SC_WEIGHT90 =36,
- SC_SPEEDPOTION0 =37,
- SC_SPEEDPOTION1 =38,
- SC_SPEEDPOTION2 =39,
- SC_STRIPWEAPON =50,
- SC_STRIPSHIELD =51,
- SC_STRIPARMOR =52,
- SC_STRIPHELM =53,
- SC_CP_WEAPON =54,
- SC_CP_SHIELD =55,
- SC_CP_ARMOR =56,
- SC_CP_HELM =57,
- SC_AUTOGUARD =58,
- SC_REFLECTSHIELD =59,
- SC_DEVOTION =60,
- SC_PROVIDENCE =61,
- SC_DEFENDER =62,
- SC_AUTOSPELL =65,
- SC_SPEARSQUICKEN =68,
- SC_EXPLOSIONSPIRITS =86,
- SC_STEELBODY =87,
- SC_COMBO =89,
- SC_FLAMELAUNCHER =90,
- SC_FROSTWEAPON =91,
- SC_LIGHTNINGLOADER =92,
- SC_SEISMICWEAPON =93,
- SC_AURABLADE =103, /* ƒI?ƒ‰ƒuƒŒ?ƒh */
- SC_PARRYING =104, /* ƒpƒŠƒCƒ“ƒO */
- SC_CONCENTRATION =105, /* ƒRƒ“ƒZƒ“ƒgƒŒ?ƒVƒ‡ƒ“ */
- SC_TENSIONRELAX =106, /* ƒeƒ“ƒVƒ‡ƒ“ƒŠƒ‰ƒbƒNƒX */
- SC_BERSERK =107, /* ƒo?ƒT?ƒN */
- SC_ASSUMPTIO =110, /* ƒAƒVƒƒƒ“ƒvƒeƒBƒI */
- SC_MAGICPOWER =113, /* –‚–@—Í?• */
- SC_TRUESIGHT =115, /* ƒgƒDƒ‹?ƒTƒCƒg */
- SC_WINDWALK =116, /* ƒEƒCƒ“ƒhƒEƒH?ƒN */
- SC_MELTDOWN =117, /* ƒƒ‹ƒgƒ_ƒEƒ“ */
- SC_CARTBOOST =118, /* ƒJ?ƒgƒu?ƒXƒg */
- SC_REJECTSWORD =120, /* ƒŠƒWƒFƒNƒgƒ\?ƒh */
- SC_MARIONETTE =121, /* ƒ}ƒŠƒIƒlƒbƒgƒRƒ“ƒgƒ?ƒ‹ */
- SC_HEADCRUSH =124, /* ƒwƒbƒhƒNƒ‰ƒbƒVƒ… */
- SC_JOINTBEAT =125, /* ƒWƒ‡ƒCƒ“ƒgƒr?ƒg */
-
- SC_STONE =128,
- SC_FREEZE =129,
- SC_STAN =130,
- SC_SLEEP =131,
- SC_POISON =132,
- SC_CURSE =133,
- SC_SILENCE =134,
- SC_CONFUSION =135,
- SC_BLIND =136,
- SC_DIVINA = SC_SILENCE,
-
- SC_SAFETYWALL =140,
- SC_PNEUMA =141,
- SC_WATERBALL =142,
- SC_ANKLE =143,
- SC_DANCING =144,
- SC_KEEPING =145,
- SC_BARRIER =146,
-
- SC_MAGICROD =149,
- SC_SIGHT =150,
- SC_RUWACH =151,
- SC_AUTOCOUNTER =152,
- SC_VOLCANO =153,
- SC_DELUGE =154,
- SC_VIOLENTGALE =155,
- SC_BLADESTOP_WAIT =156,
- SC_BLADESTOP =157,
- SC_EXTREMITYFIST =158,
- SC_GRAFFITI =159,
-
- SC_LULLABY =160,
- SC_RICHMANKIM =161,
- SC_ETERNALCHAOS =162,
- SC_DRUMBATTLE =163,
- SC_NIBELUNGEN =164,
- SC_ROKISWEIL =165,
- SC_INTOABYSS =166,
- SC_SIEGFRIED =167,
- SC_DISSONANCE =168,
- SC_WHISTLE =169,
- SC_ASSNCROS =170,
- SC_POEMBRAGI =171,
- SC_APPLEIDUN =172,
- SC_UGLYDANCE =173,
- SC_HUMMING =174,
- SC_DONTFORGETME =175,
- SC_FORTUNE =176,
- SC_SERVICE4U =177,
-
- SC_SPIDERWEB =180, /* ƒXƒpƒCƒ_?ƒEƒFƒbƒu */
- SC_MEMORIZE =181, /* ƒƒ‚ƒ‰ƒCƒY */
-// SC_DPOISON =182, /* –Ò“Å */
-
-// SC_EDP =183, /* ƒGƒtƒFƒNƒg‚ª”»–¾‚µ‚½‚çˆÚ“® */
-
- SC_WEDDING =187, //Œ‹¥—p(Œ‹¥ˆßւɂȂÁ‚Ä?‚­‚Ì‚ª?‚¢‚Æ‚©)
- SC_NOCHAT =188, //ÔƒGƒ‚?‘Ô
- SC_SPLASHER =189, /* ƒxƒiƒ€ƒXƒvƒ‰ƒbƒVƒƒ? */
- SC_SELFDESTRUCTION =190, /* Ž©”š */
-
-
-// Used by English Team
- SC_BROKNARMOR =32,
- SC_BROKNWEAPON =33,
- SC_SLOWDOWN =45, // for skill slowdown
- SC_SIGHTTRASHER =73,
-// SC_BASILICA =125, // 125 is the same id as joint break
- SC_BASILICA =102, // temporarily use this before an actual id is found [celest]
- SC_EDP =114, //
- SC_MARIONETTE2 =122, // Marionette target
- SC_ENSEMBLE =159,
- SC_FOGWALL =178,
- SC_GOSPEL =179,
- SC_LANDPROTECTOR =182,
- SC_ADAPTATION =183,
- SC_CHASEWALK =184,
- SC_ATKPOT =185, // [Valaris]
- SC_MATKPOT =186, // [Valaris]
- SC_MINDBREAKER =191,
- SC_SPELLBREAKER =192,
- SC_DPOISON =193, /* –Ò“Å */
- SC_BLOCKSKILL =194, // for disallowing the use of a skill for a time period
-
-// [Celest]
- SC_BLEEDING = 124, // Temporarily same id as headcrush
- SC_MOONLIT = 195,
- SC_LEADERSHIP = 196,
- SC_GLORYWOUNDS = 197,
- SC_SOULCOLD = 198,
- SC_HAWKEYES = 199,
- SC_BATTLEORDERS = 200,
- SC_REGENERATION = 201,
- SC_PRESERVE = 202,
-
-// -- testing various SC effects
-// SC_AURABLADE =81,
-// SC_CONCENTRATION =83,
-// SC_TENSIONRELAX =84,
-// SC_BERSERK =85,
-// SC_CALLSPIRITS =100,
-// SC_PARRYING =100,
-// SC_FREECAST =101,
-// SC_ABSORBSPIRIT =102,
-// SC_ASSUMPTIO =114,
-// SC_SHARPSHOOT =127,
-// SC_GANGSTER =184,
-// SC_CANNIBALIZE =186,
-// SC_SPHEREMINE =187,
-// SC_METEOSTORM =189,
-// SC_CASTCANCEL =190,
-// SC_SPIDERWEB =191,
-};
-extern int SkillStatusChangeTable[];
-
enum {
NV_BASIC = 1,
@@ -737,6 +566,22 @@ enum {
NPC_SELFDESTRUCTION2 = 331,
ITM_TOMAHAWK = 337,
NPC_DARKCROSS = 338,
+ NPC_DARKGRANDCROSS,
+ NPC_DARKSOULSTRIKE,
+ NPC_DARKJUPITEL,
+ // temporary names for mob skills [Celest]
+ NPC_BIND,
+ NPC_BREAKWEAPON,
+ NPC_BREAKARMOR,
+ NPC_BREAKHELM,
+ NPC_BREAKSHIELD,
+ NPC_UNDEADATTACK,
+
+ NPC_RUNAWAY = 348,
+ NPC_EXPLOSIONSPIRITS,
+ NPC_INCAGI,
+
+ NPC_RECALL = 354,
LK_AURABLADE = 355,
LK_PARRYING,
@@ -794,7 +639,8 @@ enum {
WE_BABY,
WE_CALLPARENT,
WE_CALLBABY,
- TK_RUN,
+
+ TK_RUN = 411,
TK_READYSTORM,
TK_STORMKICK,
TK_READYDOWN,
diff --git a/src/map/status.c b/src/map/status.c
new file mode 100644
index 000000000..a9967d956
--- /dev/null
+++ b/src/map/status.c
@@ -0,0 +1,5159 @@
+
+// ƒXƒe[ƒ^ƒXŒvŽZAó‘ÔˆÙ툗
+#include <time.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+
+#include "pc.h"
+#include "map.h"
+#include "pet.h"
+#include "mob.h"
+#include "clif.h"
+#include "guild.h"
+#include "skill.h"
+#include "itemdb.h"
+#include "battle.h"
+#include "chrif.h"
+#include "status.h"
+
+#include "timer.h"
+#include "nullpo.h"
+#include "script.h"
+#include "showmsg.h"
+
+/* ƒXƒLƒ‹”Ô?„ƒXƒe?ƒ^ƒXˆÙí”Ô??Š·ƒe?ƒuƒ‹ */
+int SkillStatusChangeTable[]={ /* status.h‚Ìenum‚ÌSC_***‚Æ‚ ‚킹‚邱‚Æ */
+/* 0- */
+ -1,-1,-1,-1,-1,-1,
+ SC_PROVOKE, /* ƒvƒƒ{ƒbƒN */
+ -1, 1,-1,
+/* 10- */
+ SC_SIGHT, /* ƒTƒCƒg */
+ -1,
+ SC_SAFETYWALL, /* ƒZ[ƒtƒeƒB[ƒEƒH[ƒ‹ */
+ -1,-1,-1,
+ SC_FREEZE, /* ƒtƒƒXƒgƒ_ƒCƒo? */
+ SC_STONE, /* ƒXƒg?ƒ“ƒJ?ƒX */
+ -1,-1,
+/* 20- */
+ -1,-1,-1,-1,
+ SC_RUWACH, /* ƒ‹ƒAƒt */
+ SC_PNEUMA, /* ƒjƒ…[ƒ} */
+ -1,-1,-1,
+ SC_INCREASEAGI, /* ‘¬“x?‰Á */
+/* 30- */
+ SC_DECREASEAGI, /* ‘¬“xŒ¸­ */
+ -1,
+ SC_SIGNUMCRUCIS, /* ƒVƒOƒiƒ€ƒNƒ‹ƒVƒX */
+ SC_ANGELUS, /* ƒGƒ“ƒWƒFƒ‰ƒX */
+ SC_BLESSING, /* ƒuƒŒƒbƒVƒ“ƒO */
+ -1,-1,-1,-1,-1,
+/* 40- */
+ -1,-1,-1,-1,-1,
+ SC_CONCENTRATE, /* W’†—ÍŒüã */
+ -1,-1,-1,-1,
+/* 50- */
+ -1,
+ SC_HIDING, /* ƒnƒCƒfƒBƒ“ƒO */
+ -1,-1,-1,-1,-1,-1,-1,-1,
+/* 60- */
+ SC_TWOHANDQUICKEN, /* 2HQ */
+ SC_AUTOCOUNTER,
+ -1,-1,-1,-1,
+ SC_IMPOSITIO, /* ƒCƒ“ƒ|ƒVƒeƒBƒIƒ}ƒkƒX */
+ SC_SUFFRAGIUM, /* ƒTƒtƒ‰ƒMƒEƒ€ */
+ SC_ASPERSIO, /* ƒAƒXƒyƒ‹ƒVƒI */
+ SC_BENEDICTIO, /* ¹?~•Ÿ */
+/* 70- */
+ -1,
+ SC_SLOWPOISON,
+ -1,
+ SC_KYRIE, /* ƒLƒŠƒGƒGƒŒƒCƒ\ƒ“ */
+ SC_MAGNIFICAT, /* ƒ}ƒOƒjƒtƒBƒJ?ƒg */
+ SC_GLORIA, /* ƒOƒƒŠƒA */
+ SC_DIVINA, /* ƒŒƒbƒNƒXƒfƒBƒr?ƒi */
+ -1,
+ SC_AETERNA, /* ƒŒƒbƒNƒXƒG?ƒeƒ‹ƒi */
+ -1,
+/* 80- */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+/* 90- */
+ -1,-1,
+ SC_QUAGMIRE, /* ƒNƒ@ƒOƒ}ƒCƒA */
+ -1,-1,-1,-1,-1,-1,-1,
+/* 100- */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+/* 110- */
+ -1,
+ SC_ADRENALINE, /* ƒAƒhƒŒƒiƒŠƒ“ƒ‰ƒbƒVƒ… */
+ SC_WEAPONPERFECTION,/* ƒEƒFƒ|ƒ“ƒp?ƒtƒFƒNƒVƒ‡ƒ“ */
+ SC_OVERTHRUST, /* ƒI?ƒo?ƒgƒ‰ƒXƒg */
+ SC_MAXIMIZEPOWER, /* ƒ}ƒLƒVƒ}ƒCƒYƒpƒ? */
+ -1,-1,-1,-1,-1,
+/* 120- */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+/* 130- */
+ -1,-1,-1,-1,-1,
+ SC_CLOAKING, /* ƒNƒ?ƒLƒ“ƒO */
+ SC_STAN, /* ƒ\ƒjƒbƒNƒuƒ? */
+ -1,
+ SC_ENCPOISON, /* ƒGƒ“ƒ`ƒƒƒ“ƒgƒ|ƒCƒYƒ“ */
+ SC_POISONREACT, /* ƒ|ƒCƒYƒ“ƒŠƒAƒNƒg */
+/* 140- */
+ SC_POISON, /* ƒxƒmƒ€ƒ_ƒXƒg */
+ SC_SPLASHER, /* ƒxƒiƒ€ƒXƒvƒ‰ƒbƒVƒƒ? */
+ -1,
+ SC_TRICKDEAD, /* Ž€‚ñ‚¾‚Ó‚è */
+ -1,-1,SC_AUTOBERSERK,-1,-1,-1,
+/* 150- */
+ -1,-1,-1,-1,-1,
+ SC_LOUD, /* ƒ‰ƒEƒhƒ{ƒCƒX */
+ -1,
+ SC_ENERGYCOAT, /* ƒGƒiƒW?ƒR?ƒg */
+ -1,-1,
+/* 160- */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,
+ SC_SELFDESTRUCTION,
+ -1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,
+ SC_KEEPING,
+ -1,-1,
+ SC_BARRIER,
+ -1,-1,
+ SC_HALLUCINATION,
+ -1,-1,
+/* 210- */
+ -1,-1,-1,-1,-1,
+ SC_STRIPWEAPON,
+ SC_STRIPSHIELD,
+ SC_STRIPARMOR,
+ SC_STRIPHELM,
+ -1,
+/* 220- */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+/* 230- */
+ -1,-1,-1,-1,
+ SC_CP_WEAPON,
+ SC_CP_SHIELD,
+ SC_CP_ARMOR,
+ SC_CP_HELM,
+ -1,-1,
+/* 240- */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,
+ SC_AUTOGUARD,
+/* 250- */
+ -1,-1,
+ SC_REFLECTSHIELD,
+ -1,-1,
+ SC_DEVOTION,
+ SC_PROVIDENCE,
+ SC_DEFENDER,
+ SC_SPEARSQUICKEN,
+ -1,
+/* 260- */
+ -1,-1,-1,-1,-1,-1,-1,-1,
+ SC_STEELBODY,
+ SC_BLADESTOP_WAIT,
+/* 270- */
+ SC_EXPLOSIONSPIRITS,
+ SC_EXTREMITYFIST,
+ -1,-1,-1,-1,
+ SC_MAGICROD,
+ -1,-1,-1,
+/* 280- */
+ SC_FLAMELAUNCHER,
+ SC_FROSTWEAPON,
+ SC_LIGHTNINGLOADER,
+ SC_SEISMICWEAPON,
+ -1,
+ SC_VOLCANO,
+ SC_DELUGE,
+ SC_VIOLENTGALE,
+ SC_LANDPROTECTOR,
+ -1,
+/* 290- */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+/* 300- */
+ -1,-1,-1,-1,-1,-1,
+ SC_LULLABY,
+ SC_RICHMANKIM,
+ SC_ETERNALCHAOS,
+ SC_DRUMBATTLE,
+/* 310- */
+ SC_NIBELUNGEN,
+ SC_ROKISWEIL,
+ SC_INTOABYSS,
+ SC_SIEGFRIED,
+ -1,-1,-1,
+ SC_DISSONANCE,
+ -1,
+ SC_WHISTLE,
+/* 320- */
+ SC_ASSNCROS,
+ SC_POEMBRAGI,
+ SC_APPLEIDUN,
+ -1,-1,
+ SC_UGLYDANCE,
+ -1,
+ SC_HUMMING,
+ SC_DONTFORGETME,
+ SC_FORTUNE,
+/* 330- */
+ SC_SERVICE4U,
+ SC_SELFDESTRUCTION,
+ -1,-1,-1,-1,-1,-1,-1,-1,
+/* 340- */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+/* 350- */
+ -1,-1,-1,-1,-1,
+ SC_AURABLADE,
+ SC_PARRYING,
+ SC_CONCENTRATION,
+ SC_TENSIONRELAX,
+ SC_BERSERK,
+/* 360- */
+ SC_BERSERK,
+ SC_ASSUMPTIO,
+ SC_BASILICA,
+ -1,-1,-1,
+ SC_MAGICPOWER,
+ -1,
+ SC_SACRIFICE,
+ SC_GOSPEL,
+/* 370- */
+ -1,-1,-1,-1,-1,-1,-1,-1,
+ SC_EDP,
+ -1,
+/* 380- */
+ SC_TRUESIGHT,
+ -1,-1,
+ SC_WINDWALK,
+ SC_MELTDOWN,
+ -1,-1,
+ SC_CARTBOOST,
+ -1,
+ SC_CHASEWALK,
+/* 390- */
+ SC_REJECTSWORD,
+ -1,-1,-1,-1,
+ SC_MOONLIT,
+ SC_MARIONETTE,
+ -1,
+ SC_BLEEDING,
+ SC_JOINTBEAT,
+/* 400 */
+ -1,-1,
+ SC_MINDBREAKER,
+ SC_MEMORIZE,
+ SC_FOGWALL,
+ SC_SPIDERWEB,
+ -1,-1,
+ SC_BABY,
+ -1,
+/* 410- */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+};
+
+static int max_weight_base[MAX_PC_CLASS];
+static int hp_coefficient[MAX_PC_CLASS];
+static int hp_coefficient2[MAX_PC_CLASS];
+static int hp_sigma_val[MAX_PC_CLASS][MAX_LEVEL];
+static int sp_coefficient[MAX_PC_CLASS];
+static int aspd_base[MAX_PC_CLASS][20];
+static int refinebonus[5][3]; // ¸˜Bƒ{[ƒiƒXƒe[ƒuƒ‹(refine_db.txt)
+int percentrefinery[5][10]; // ¸˜B¬Œ÷—¦(refine_db.txt)
+static int atkmods[3][20]; // •ŠíATKƒTƒCƒYC³(size_fix.txt)
+static char job_bonus[3][MAX_PC_CLASS][MAX_LEVEL];
+
+int current_equip_item_index; //Contains inventory index of an equipped item. To pass it into the EQUP_SCRIPT [Lupus]
+//we need it for new cards 15 Feb 2005, to check if the combo cards are insrerted into the CURRENT weapon only
+//to avoid cards exploits
+
+/*==========================================
+ * ¸˜Bƒ{[ƒiƒX
+ *------------------------------------------
+ */
+int status_getrefinebonus(int lv,int type)
+{
+ if (lv >= 0 && lv < 5 && type >= 0 && type < 3)
+ return refinebonus[lv][type];
+ return 0;
+}
+
+/*==========================================
+ * ¸˜B¬Œ÷—¦
+ *------------------------------------------
+ */
+int status_percentrefinery(struct map_session_data *sd,struct item *item)
+{
+ int percent;
+
+ nullpo_retr(0, item);
+ percent=percentrefinery[itemdb_wlv(item->nameid)][(int)item->refine];
+
+ percent += pc_checkskill(sd,BS_WEAPONRESEARCH); // •ŠíŒ¤‹†ƒXƒLƒ‹ŠŽ
+
+ // Šm—¦‚Ì—LŒø”͈̓`ƒFƒbƒN
+ if( percent > 100 ){
+ percent = 100;
+ }
+ if( percent < 0 ){
+ percent = 0;
+ }
+
+ return percent;
+}
+
+/*==========================================
+ * ƒpƒ‰ƒ[ƒ^ŒvŽZ
+ * first==0‚ÌŽžAŒvŽZ‘Îۂ̃pƒ‰ƒ[ƒ^‚ªŒÄ‚Ño‚µ‘O‚©‚ç
+ * •Ï ‰»‚µ‚½ê‡Ž©“®‚Åsend‚·‚邪A
+ * ”\“®“I‚ɕω»‚³‚¹‚½ƒpƒ‰ƒ[ƒ^‚ÍŽ©‘O‚Åsend‚·‚邿‚¤‚É
+ *------------------------------------------
+ */
+
+int status_calc_pc(struct map_session_data* sd,int first)
+{
+ int b_speed,b_max_hp,b_max_sp,b_hp,b_sp,b_weight,b_max_weight,b_paramb[6],b_parame[6],b_hit,b_flee;
+ int b_aspd,b_watk,b_def,b_watk2,b_def2,b_flee2,b_critical,b_attackrange,b_matk1,b_matk2,b_mdef,b_mdef2,b_class;
+ int b_base_atk;
+ struct skill b_skill[MAX_SKILL];
+ int i,bl,index;
+ int skill,aspd_rate,wele,wele_,def_ele,refinedef=0;
+ int pele=0,pdef_ele=0;
+ int str,dstr,dex;
+ struct pc_base_job s_class;
+
+ nullpo_retr(0, sd);
+
+ //?¶‚â—{Žq‚Ìꇂ̌³‚ÌE‹Æ‚ðŽZo‚·‚é
+ s_class = pc_calc_base_job(sd->status.class_);
+
+ b_speed = sd->speed;
+ b_max_hp = sd->status.max_hp;
+ b_max_sp = sd->status.max_sp;
+ b_hp = sd->status.hp;
+ b_sp = sd->status.sp;
+ b_weight = sd->weight;
+ b_max_weight = sd->max_weight;
+ memcpy(b_paramb,&sd->paramb,sizeof(b_paramb));
+ memcpy(b_parame,&sd->paramc,sizeof(b_parame));
+ memcpy(b_skill,&sd->status.skill,sizeof(b_skill));
+ b_hit = sd->hit;
+ b_flee = sd->flee;
+ b_aspd = sd->aspd;
+ b_watk = sd->watk;
+ b_def = sd->def;
+ b_watk2 = sd->watk2;
+ b_def2 = sd->def2;
+ b_flee2 = sd->flee2;
+ b_critical = sd->critical;
+ b_attackrange = sd->attackrange;
+ b_matk1 = sd->matk1;
+ b_matk2 = sd->matk2;
+ b_mdef = sd->mdef;
+ b_mdef2 = sd->mdef2;
+ b_class = sd->view_class;
+ sd->view_class = sd->status.class_;
+ b_base_atk = sd->base_atk;
+
+ pc_calc_skilltree(sd); // ƒXƒLƒ‹ƒcƒŠ?‚ÌŒvŽZ
+
+ sd->max_weight = max_weight_base[s_class.job]+sd->status.str*300;
+
+ if(first&1) {
+ sd->weight=0;
+ for(i=0;i<MAX_INVENTORY;i++){
+ if(sd->status.inventory[i].nameid==0 || sd->inventory_data[i] == NULL)
+ continue;
+ sd->weight += sd->inventory_data[i]->weight*sd->status.inventory[i].amount;
+ }
+ sd->cart_max_weight=battle_config.max_cart_weight;
+ sd->cart_weight=0;
+ sd->cart_max_num=MAX_CART;
+ sd->cart_num=0;
+ for(i=0;i<MAX_CART;i++){
+ if(sd->status.cart[i].nameid==0)
+ continue;
+ sd->cart_weight+=itemdb_weight(sd->status.cart[i].nameid)*sd->status.cart[i].amount;
+ sd->cart_num++;
+ }
+ }
+
+ memset(sd->paramb,0,sizeof(sd->paramb));
+ memset(sd->parame,0,sizeof(sd->parame));
+ sd->hit = 0;
+ sd->flee = 0;
+ sd->flee2 = 0;
+ sd->critical = 0;
+ sd->aspd = 0;
+ sd->watk = 0;
+ sd->def = 0;
+ sd->mdef = 0;
+ sd->watk2 = 0;
+ sd->def2 = 0;
+ sd->mdef2 = 0;
+ sd->status.max_hp = 0;
+ sd->status.max_sp = 0;
+ sd->attackrange = 0;
+ sd->attackrange_ = 0;
+ sd->atk_ele = 0;
+ sd->def_ele = 0;
+ sd->star =0;
+ sd->overrefine =0;
+ sd->matk1 =0;
+ sd->matk2 =0;
+ sd->speed = DEFAULT_WALK_SPEED ;
+ sd->hprate=battle_config.hp_rate;
+ sd->sprate=battle_config.sp_rate;
+ sd->castrate=100;
+ sd->delayrate=100;
+ sd->dsprate=100;
+ sd->base_atk=0;
+ sd->arrow_atk=0;
+ sd->arrow_ele=0;
+ sd->arrow_hit=0;
+ sd->arrow_range=0;
+ sd->nhealhp=sd->nhealsp=sd->nshealhp=sd->nshealsp=sd->nsshealhp=sd->nsshealsp=0;
+ memset(sd->addele,0,sizeof(sd->addele));
+ memset(sd->addrace,0,sizeof(sd->addrace));
+ memset(sd->addsize,0,sizeof(sd->addsize));
+ memset(sd->addele_,0,sizeof(sd->addele_));
+ memset(sd->addrace_,0,sizeof(sd->addrace_));
+ memset(sd->addsize_,0,sizeof(sd->addsize_));
+ memset(sd->subele,0,sizeof(sd->subele));
+ memset(sd->subrace,0,sizeof(sd->subrace));
+ memset(sd->addeff,0,sizeof(sd->addeff));
+ memset(sd->addeff2,0,sizeof(sd->addeff2));
+ memset(sd->reseff,0,sizeof(sd->reseff));
+ memset(&sd->special_state,0,sizeof(sd->special_state));
+ memset(sd->weapon_coma_ele,0,sizeof(sd->weapon_coma_ele));
+ memset(sd->weapon_coma_race,0,sizeof(sd->weapon_coma_race));
+ memset(sd->weapon_atk,0,sizeof(sd->weapon_atk));
+ memset(sd->weapon_atk_rate,0,sizeof(sd->weapon_atk_rate));
+
+ sd->watk_ = 0; //“ñ“—¬—p(?)
+ sd->watk_2 = 0;
+ sd->atk_ele_ = 0;
+ sd->star_ = 0;
+ sd->overrefine_ = 0;
+
+ sd->aspd_rate = 100;
+ sd->speed_rate = 100;
+ sd->hprecov_rate = 100;
+ sd->sprecov_rate = 100;
+ sd->critical_def = 0;
+ sd->double_rate = 0;
+ sd->near_attack_def_rate = sd->long_attack_def_rate = 0;
+ sd->atk_rate = sd->matk_rate = 100;
+ sd->ignore_def_ele = sd->ignore_def_race = 0;
+ sd->ignore_def_ele_ = sd->ignore_def_race_ = 0;
+ sd->ignore_mdef_ele = sd->ignore_mdef_race = 0;
+ sd->arrow_cri = 0;
+ sd->magic_def_rate = sd->misc_def_rate = 0;
+ memset(sd->arrow_addele,0,sizeof(sd->arrow_addele));
+ memset(sd->arrow_addrace,0,sizeof(sd->arrow_addrace));
+ memset(sd->arrow_addsize,0,sizeof(sd->arrow_addsize));
+ memset(sd->arrow_addeff,0,sizeof(sd->arrow_addeff));
+ memset(sd->arrow_addeff2,0,sizeof(sd->arrow_addeff2));
+ memset(sd->magic_addele,0,sizeof(sd->magic_addele));
+ memset(sd->magic_addrace,0,sizeof(sd->magic_addrace));
+ memset(sd->magic_subrace,0,sizeof(sd->magic_subrace));
+ sd->perfect_hit = 0;
+ sd->critical_rate = sd->hit_rate = sd->flee_rate = sd->flee2_rate = 100;
+ sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100;
+ sd->def_ratio_atk_ele = sd->def_ratio_atk_ele_ = 0;
+ sd->def_ratio_atk_race = sd->def_ratio_atk_race_ = 0;
+ sd->get_zeny_num = 0;
+ sd->add_damage_class_count = sd->add_damage_class_count_ = sd->add_magic_damage_class_count = 0;
+ sd->add_def_class_count = sd->add_mdef_class_count = 0;
+ sd->monster_drop_item_count = 0;
+ memset(sd->add_damage_classrate,0,sizeof(sd->add_damage_classrate));
+ memset(sd->add_damage_classrate_,0,sizeof(sd->add_damage_classrate_));
+ memset(sd->add_magic_damage_classrate,0,sizeof(sd->add_magic_damage_classrate));
+ memset(sd->add_def_classrate,0,sizeof(sd->add_def_classrate));
+ memset(sd->add_mdef_classrate,0,sizeof(sd->add_mdef_classrate));
+ memset(sd->monster_drop_race,0,sizeof(sd->monster_drop_race));
+ memset(sd->monster_drop_itemrate,0,sizeof(sd->monster_drop_itemrate));
+ sd->speed_add_rate = sd->aspd_add_rate = 100;
+ sd->double_add_rate = sd->perfect_hit_add = sd->get_zeny_add_num = 0;
+ sd->splash_range = sd->splash_add_range = 0;
+ sd->autospell_id = sd->autospell_lv = sd->autospell_rate = 0;
+ sd->hp_drain_rate = sd->hp_drain_per = sd->sp_drain_rate = sd->sp_drain_per = 0;
+ sd->hp_drain_rate_ = sd->hp_drain_per_ = sd->sp_drain_rate_ = sd->sp_drain_per_ = 0;
+ sd->short_weapon_damage_return = sd->long_weapon_damage_return = 0;
+ sd->magic_damage_return = 0; //AppleGirl Was Here
+ sd->random_attack_increase_add = sd->random_attack_increase_per = 0;
+ sd->hp_drain_value = sd->hp_drain_value_ = sd->sp_drain_value = sd->sp_drain_value_ = 0;
+ sd->unbreakable_equip = 0;
+
+ sd->break_weapon_rate = sd->break_armor_rate = 0;
+ sd->add_steal_rate = 0;
+ sd->crit_atk_rate = 0;
+ sd->no_regen = 0;
+ sd->unstripable_equip = 0;
+ sd->autospell2_id = sd->autospell2_lv = sd->autospell2_rate = 0;
+ memset(sd->critaddrace,0,sizeof(sd->critaddrace));
+ memset(sd->addeff3,0,sizeof(sd->addeff3));
+ memset(sd->addeff3_type,0,sizeof(sd->addeff3_type));
+ memset(sd->skillatk,0,sizeof(sd->skillatk));
+ sd->add_damage_class_count = sd->add_damage_class_count_ = sd->add_magic_damage_class_count = 0;
+ sd->add_def_class_count = sd->add_mdef_class_count = 0;
+ sd->add_damage_class_count2 = 0;
+ memset(sd->add_damage_classid,0,sizeof(sd->add_damage_classid));
+ memset(sd->add_damage_classid_,0,sizeof(sd->add_damage_classid_));
+ memset(sd->add_magic_damage_classid,0,sizeof(sd->add_magic_damage_classid));
+ memset(sd->add_damage_classrate,0,sizeof(sd->add_damage_classrate));
+ memset(sd->add_damage_classrate_,0,sizeof(sd->add_damage_classrate_));
+ memset(sd->add_magic_damage_classrate,0,sizeof(sd->add_magic_damage_classrate));
+ memset(sd->add_def_classid,0,sizeof(sd->add_def_classid));
+ memset(sd->add_def_classrate,0,sizeof(sd->add_def_classrate));
+ memset(sd->add_mdef_classid,0,sizeof(sd->add_mdef_classid));
+ memset(sd->add_mdef_classrate,0,sizeof(sd->add_mdef_classrate));
+ memset(sd->add_damage_classid2,0,sizeof(sd->add_damage_classid2));
+ memset(sd->add_damage_classrate2,0,sizeof(sd->add_damage_classrate2));
+ sd->sp_gain_value = 0;
+ sd->ignore_def_mob = sd->ignore_def_mob_ = 0;
+ sd->hp_loss_rate = sd->hp_loss_value = sd->hp_loss_type = 0;
+ memset(sd->addrace2,0,sizeof(sd->addrace2));
+ memset(sd->addrace2_,0,sizeof(sd->addrace2_));
+ sd->hp_gain_value = sd->sp_drain_type = 0;
+ memset(sd->subsize,0,sizeof(sd->subsize));
+ memset(sd->unequip_losehp,0,sizeof(sd->unequip_losehp));
+ memset(sd->unequip_losesp,0,sizeof(sd->unequip_losesp));
+ memset(sd->subrace2,0,sizeof(sd->subrace2));
+ memset(sd->expaddrace,0,sizeof(sd->expaddrace));
+ memset(sd->sp_gain_race,0,sizeof(sd->sp_gain_race));
+
+ if(!sd->disguiseflag && sd->disguise) {
+ sd->disguise=0;
+ clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
+ clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
+ clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
+ clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
+ clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
+ clif_clearchar(&sd->bl, 9);
+ pc_setpos(sd, sd->mapname, sd->bl.x, sd->bl.y, 3);
+ }
+
+ if (sd->status.guild_id > 0) {
+ struct guild *g = guild_search(sd->status.guild_id);
+ if (g && strcmp(sd->status.name,g->master)==0)
+ sd->state.gmaster_flag = (int)g;
+ }
+
+ for(i=0;i<10;i++) {
+ current_equip_item_index = index = sd->equip_index[i]; //We pass INDEX to current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus]
+ if(index < 0)
+ continue;
+ if(i == 9 && sd->equip_index[8] == index)
+ continue;
+ if(i == 5 && sd->equip_index[4] == index)
+ continue;
+ if(i == 6 && (sd->equip_index[5] == index || sd->equip_index[4] == index))
+ continue;
+
+ if(sd->inventory_data[index]) {
+ if(sd->inventory_data[index]->type == 4) {
+ if(sd->status.inventory[index].card[0]!=0x00ff && sd->status.inventory[index].card[0]!=0x00fe && sd->status.inventory[index].card[0]!=(short)0xff00) {
+ int j;
+ for(j=0;j<sd->inventory_data[index]->slot;j++){ // ƒJ?ƒh
+ int c=sd->status.inventory[index].card[j];
+ if(c>0){
+ if(i == 8 && sd->status.inventory[index].equip == 0x20)
+ sd->state.lr_flag = 1;
+ run_script(itemdb_equipscript(c),0,sd->bl.id,0);
+ sd->state.lr_flag = 0;
+ }
+ }
+ }
+ }
+ else if(sd->inventory_data[index]->type==5){ // –h‹ï
+ if(sd->status.inventory[index].card[0]!=0x00ff && sd->status.inventory[index].card[0]!=0x00fe && sd->status.inventory[index].card[0]!=(short)0xff00) {
+ int j;
+ for(j=0;j<sd->inventory_data[index]->slot;j++){ // ƒJ?ƒh
+ int c=sd->status.inventory[index].card[j];
+ if(c>0)
+ run_script(itemdb_equipscript(c),0,sd->bl.id,0);
+ }
+ }
+ }
+ }
+ }
+ wele = sd->atk_ele;
+ wele_ = sd->atk_ele_;
+ def_ele = sd->def_ele;
+ if(sd->status.pet_id > 0) {
+ struct pet_data *pd=sd->pd;
+ if((pd && battle_config.pet_status_support==1) && (battle_config.pet_equip_required==0 || (battle_config.pet_equip_required && pd->equip > 0))) {
+ if(sd->status.pet_id > 0 && sd->petDB && sd->pet.intimate > 0 &&
+ pd->state.skillbonus == 1) {
+ pc_bonus(sd,pd->skillbonustype,pd->skillbonusval);
+// run_script(sd->petDB->script,0,sd->bl.id,0);
+ }
+ pele = sd->atk_ele;
+ pdef_ele = sd->def_ele;
+ sd->atk_ele = sd->def_ele = 0;
+ }
+ }
+ memcpy(sd->paramcard,sd->parame,sizeof(sd->paramcard));
+
+ // ?”õ•i‚É‚æ‚éƒXƒe?ƒ^ƒX?‰»‚Í‚±‚±‚Å?s
+ for(i=0;i<10;i++) {
+ current_equip_item_index = index = sd->equip_index[i]; //We pass INDEX to current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus]
+ if(index < 0)
+ continue;
+ if(i == 9 && sd->equip_index[8] == index)
+ continue;
+ if(i == 5 && sd->equip_index[4] == index)
+ continue;
+ if(i == 6 && (sd->equip_index[5] == index || sd->equip_index[4] == index))
+ continue;
+ if(sd->inventory_data[index]) {
+ sd->def += sd->inventory_data[index]->def;
+ if(sd->inventory_data[index]->type == 4) {
+ int r,wlv = sd->inventory_data[index]->wlv;
+ if(i == 8 && sd->status.inventory[index].equip == 0x20) {
+ //“ñ“—¬—pƒf?ƒ^“ü—Í
+ sd->watk_ += sd->inventory_data[index]->atk;
+ sd->watk_2 = (r=sd->status.inventory[index].refine)* // ¸?U?—Í
+ refinebonus[wlv][0];
+ if( (r-=refinebonus[wlv][2])>0 ) // ‰ß?¸?ƒ{?ƒiƒX
+ sd->overrefine_ = r*refinebonus[wlv][1];
+
+ if(sd->status.inventory[index].card[0]==0x00ff){ // »‘¢•Ší
+ sd->star_ = (sd->status.inventory[index].card[1]>>8); // ¯‚Ì‚©‚¯‚ç
+ wele_= (sd->status.inventory[index].card[1]&0x0f); // ? «
+ }
+ sd->attackrange_ += sd->inventory_data[index]->range;
+ sd->state.lr_flag = 1;
+ run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0);
+ sd->state.lr_flag = 0;
+ }
+ else { //“ñ“—¬•ŠíˆÈŠO
+ sd->watk += sd->inventory_data[index]->atk;
+ sd->watk2 += (r=sd->status.inventory[index].refine)* // ¸?U?—Í
+ refinebonus[wlv][0];
+ if( (r-=refinebonus[wlv][2])>0 ) // ‰ß?¸?ƒ{?ƒiƒX
+ sd->overrefine += r*refinebonus[wlv][1];
+
+ if(sd->status.inventory[index].card[0]==0x00ff){ // »‘¢•Ší
+ sd->star += (sd->status.inventory[index].card[1]>>8); // ¯‚Ì‚©‚¯‚ç
+ wele = (sd->status.inventory[index].card[1]&0x0f); // ? «
+ }
+ sd->attackrange += sd->inventory_data[index]->range;
+ run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0);
+ }
+ }
+ else if(sd->inventory_data[index]->type == 5) {
+ sd->watk += sd->inventory_data[index]->atk;
+ refinedef += sd->status.inventory[index].refine*refinebonus[0][0];
+ run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0);
+ }
+ }
+ }
+
+ if(sd->equip_index[10] >= 0){ // –î
+ index = sd->equip_index[10];
+ if(sd->inventory_data[index]){ //‚Ü‚¾?«‚ª“ü‚Á‚Ä‚¢‚È‚¢
+ sd->state.lr_flag = 2;
+ run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0);
+ sd->state.lr_flag = 0;
+ sd->arrow_atk += sd->inventory_data[index]->atk;
+ }
+ }
+ sd->def += (refinedef+50)/100;
+
+ if(sd->attackrange < 1) sd->attackrange = 1;
+ if(sd->attackrange_ < 1) sd->attackrange_ = 1;
+ if(sd->attackrange < sd->attackrange_)
+ sd->attackrange = sd->attackrange_;
+ if(sd->status.weapon == 11)
+ sd->attackrange += sd->arrow_range;
+ if(wele > 0)
+ sd->atk_ele = wele;
+ if(wele_ > 0)
+ sd->atk_ele_ = wele_;
+ if(def_ele > 0)
+ sd->def_ele = def_ele;
+ if(battle_config.pet_status_support) {
+ if(pele > 0 && !sd->atk_ele)
+ sd->atk_ele = pele;
+ if(pdef_ele > 0 && !sd->def_ele)
+ sd->def_ele = pdef_ele;
+ }
+ sd->double_rate += sd->double_add_rate;
+ sd->perfect_hit += sd->perfect_hit_add;
+ sd->get_zeny_num += sd->get_zeny_add_num;
+ sd->splash_range += sd->splash_add_range;
+ if(sd->speed_add_rate != 100)
+ sd->speed_rate += sd->speed_add_rate - 100;
+ if(sd->aspd_add_rate != 100)
+ sd->aspd_rate += sd->aspd_add_rate - 100;
+
+ // •ŠíATKƒTƒCƒY•â³ (‰EŽè)
+ sd->atkmods[0] = atkmods[0][sd->weapontype1];
+ sd->atkmods[1] = atkmods[1][sd->weapontype1];
+ sd->atkmods[2] = atkmods[2][sd->weapontype1];
+ //•ŠíATKƒTƒCƒY•â³ (¶Žè)
+ sd->atkmods_[0] = atkmods[0][sd->weapontype2];
+ sd->atkmods_[1] = atkmods[1][sd->weapontype2];
+ sd->atkmods_[2] = atkmods[2][sd->weapontype2];
+
+ // jobƒ{?ƒiƒX•ª
+ for(i=0;i<sd->status.job_level && i<MAX_LEVEL;i++){
+ if(job_bonus[s_class.upper][s_class.job][i])
+ sd->paramb[job_bonus[s_class.upper][s_class.job][i]-1]++;
+ }
+
+ if( (skill=pc_checkskill(sd,MC_INCCARRY))>0 ) // skill can be used with an item now, thanks to orn [Valaris]
+ sd->max_weight += skill*2000;
+
+ if( (skill=pc_checkskill(sd,AC_OWL))>0 ) // ‚Ó‚­‚낤‚Ì–Ú
+ sd->paramb[4] += skill;
+
+ if((skill=pc_checkskill(sd,BS_HILTBINDING))>0) { // Hilt binding gives +1 str +4 atk
+ sd->paramb[0] ++;
+ sd->base_atk += 4;
+ }
+ if((skill=pc_checkskill(sd,SA_DRAGONOLOGY))>0 ){ // Dragonology increases +1 int every 2 levels
+ sd->paramb[3] += (int) ((skill+1)*0.5);
+ }
+
+ // ƒXƒe?ƒ^ƒX?‰»‚É‚æ‚éŠî–{ƒpƒ‰ƒ?ƒ^•â³
+ if(sd->sc_count){
+ if(sd->sc_data[SC_CONCENTRATE].timer!=-1 && sd->sc_data[SC_QUAGMIRE].timer == -1){ // W’†—ÍŒüã
+ sd->paramb[1]+= (sd->status.agi+sd->paramb[1]+sd->parame[1]-sd->paramcard[1])*(2+sd->sc_data[SC_CONCENTRATE].val1)/100;
+ sd->paramb[4]+= (sd->status.dex+sd->paramb[4]+sd->parame[4]-sd->paramcard[4])*(2+sd->sc_data[SC_CONCENTRATE].val1)/100;
+ }
+ if(sd->sc_data[SC_INCREASEAGI].timer!=-1){ // ‘¬“x?‰Á
+ sd->paramb[1]+= 2+sd->sc_data[SC_INCREASEAGI].val1;
+ sd->speed -= sd->speed *25/100;
+ }
+ if(sd->sc_data[SC_DECREASEAGI].timer!=-1) { // ‘¬“xŒ¸­(agi‚Íbattle.c‚Å)
+ sd->speed = sd->speed *125/100;
+ sd->paramb[1] -= 2 + sd->sc_data[SC_DECREASEAGI].val1; // reduce agility [celest]
+ }
+ if(sd->sc_data[SC_CLOAKING].timer!=-1) {
+ sd->critical_rate += 100; // critical increases
+ sd->speed = sd->speed * (sd->sc_data[SC_CLOAKING].val3-sd->sc_data[SC_CLOAKING].val1*3) /100;
+ }
+ if(sd->sc_data[SC_CHASEWALK].timer!=-1) {
+ sd->speed = sd->speed * sd->sc_data[SC_CHASEWALK].val3 /100; // slow down by chasewalk
+ if(sd->sc_data[SC_CHASEWALK].val4)
+ sd->paramb[0] += (1<<(sd->sc_data[SC_CHASEWALK].val1-1)); // increases strength after 10 seconds
+ }
+ if(sd->sc_data[SC_SLOWDOWN].timer!=-1)
+ sd->speed = sd->speed*150/100;
+ if(sd->sc_data[SC_SPEEDUP0].timer!=-1 && sd->sc_data[SC_INCREASEAGI].timer==-1)
+ sd->speed -= sd->speed*25/100;
+ if(sd->sc_data[SC_BLESSING].timer!=-1){ // ƒuƒŒƒbƒVƒ“ƒO
+ sd->paramb[0]+= sd->sc_data[SC_BLESSING].val1;
+ sd->paramb[3]+= sd->sc_data[SC_BLESSING].val1;
+ sd->paramb[4]+= sd->sc_data[SC_BLESSING].val1;
+ }
+ if(sd->sc_data[SC_GLORIA].timer!=-1) // ƒOƒƒŠƒA
+ sd->paramb[5]+= 30;
+ if(sd->sc_data[SC_LOUD].timer!=-1 && sd->sc_data[SC_QUAGMIRE].timer == -1) // ƒ‰ƒEƒhƒ{ƒCƒX
+ sd->paramb[0]+= 4;
+ if(sd->sc_data[SC_QUAGMIRE].timer!=-1){ // ƒNƒ@ƒOƒ}ƒCƒA
+ //int agib = (sd->status.agi+sd->paramb[1]+sd->parame[1])*(sd->sc_data[SC_QUAGMIRE].val1*10)/100;
+ //int dexb = (sd->status.dex+sd->paramb[4]+sd->parame[4])*(sd->sc_data[SC_QUAGMIRE].val1*10)/100;
+ //sd->paramb[1]-= agib > 50 ? 50 : agib;
+ //sd->paramb[4]-= dexb > 50 ? 50 : dexb;
+ sd->paramb[1]-= sd->sc_data[SC_QUAGMIRE].val1*5;
+ sd->paramb[4]-= sd->sc_data[SC_QUAGMIRE].val1*5;
+ sd->speed = sd->speed*3/2;
+ }
+ if(sd->sc_data[SC_TRUESIGHT].timer!=-1){ // ƒgƒDƒ‹?ƒTƒCƒg
+ sd->paramb[0]+= 5;
+ sd->paramb[1]+= 5;
+ sd->paramb[2]+= 5;
+ sd->paramb[3]+= 5;
+ sd->paramb[4]+= 5;
+ sd->paramb[5]+= 5;
+ }
+ if(sd->sc_data[SC_MARIONETTE].timer!=-1){
+ // skip partner checking -- should be handled in status_change_timer
+ //struct map_session_data *psd = map_id2sd(sd->sc_data[SC_MARIONETTE2].val3);
+ //if (psd) { // if partner is found
+ sd->paramb[0]-= sd->status.str/2; // bonuses not included
+ sd->paramb[1]-= sd->status.agi/2;
+ sd->paramb[2]-= sd->status.vit/2;
+ sd->paramb[3]-= sd->status.int_/2;
+ sd->paramb[4]-= sd->status.dex/2;
+ sd->paramb[5]-= sd->status.luk/2;
+ //}
+ }
+ else if(sd->sc_data[SC_MARIONETTE2].timer!=-1){
+ struct map_session_data *psd = map_id2sd(sd->sc_data[SC_MARIONETTE2].val3);
+ if (psd) { // if partner is found
+ sd->paramb[0] += sd->status.str+psd->status.str/2 > 99 ? 99-sd->status.str : psd->status.str/2;
+ sd->paramb[1] += sd->status.agi+psd->status.agi/2 > 99 ? 99-sd->status.agi : psd->status.agi/2;
+ sd->paramb[2] += sd->status.vit+psd->status.vit/2 > 99 ? 99-sd->status.vit : psd->status.vit/2;
+ sd->paramb[3] += sd->status.int_+psd->status.int_/2 > 99 ? 99-sd->status.int_ : psd->status.int_/2;
+ sd->paramb[4] += sd->status.dex+psd->status.dex/2 > 99 ? 99-sd->status.dex : psd->status.dex/2;
+ sd->paramb[5] += sd->status.luk+psd->status.luk/2 > 99 ? 99-sd->status.luk : psd->status.luk/2;
+ }
+ }
+ if(sd->sc_data[SC_GOSPEL].timer!=-1 && sd->sc_data[SC_GOSPEL].val4 == BCT_PARTY){
+ if (sd->sc_data[SC_GOSPEL].val3 == 6) {
+ sd->paramb[0]+= 2;
+ sd->paramb[1]+= 2;
+ sd->paramb[2]+= 2;
+ sd->paramb[3]+= 2;
+ sd->paramb[4]+= 2;
+ sd->paramb[5]+= 2;
+ }
+ }
+ // New guild skills - Celest
+ if (sd->sc_data[SC_BATTLEORDERS].timer != -1) {
+ sd->paramb[0]+= 5;
+ sd->paramb[3]+= 5;
+ sd->paramb[4]+= 5;
+ }
+ if (sd->sc_data[SC_GUILDAURA].timer != -1) {
+ if (sd->sc_data[SC_GUILDAURA].val4 & 1<<0)
+ sd->paramb[0] += 2;
+ if (sd->sc_data[SC_GUILDAURA].val4 & 1<<1)
+ sd->paramb[2] += 2;
+ if (sd->sc_data[SC_GUILDAURA].val4 & 1<<2)
+ sd->paramb[1] += 2;
+ if (sd->sc_data[SC_GUILDAURA].val4 & 1<<3)
+ sd->paramb[4] += 2;
+ }
+ }
+
+ //1“x‚àŽ€‚ñ‚łȂ¢Job70ƒXƒpƒmƒr‚É+10
+ if(s_class.job == 23 && sd->die_counter == 0 && sd->status.job_level >= 70){
+ sd->paramb[0]+= 15;
+ sd->paramb[1]+= 15;
+ sd->paramb[2]+= 15;
+ sd->paramb[3]+= 15;
+ sd->paramb[4]+= 15;
+ sd->paramb[5]+= 15;
+ }
+ sd->paramc[0]=sd->status.str+sd->paramb[0]+sd->parame[0];
+ sd->paramc[1]=sd->status.agi+sd->paramb[1]+sd->parame[1];
+ sd->paramc[2]=sd->status.vit+sd->paramb[2]+sd->parame[2];
+ sd->paramc[3]=sd->status.int_+sd->paramb[3]+sd->parame[3];
+ sd->paramc[4]=sd->status.dex+sd->paramb[4]+sd->parame[4];
+ sd->paramc[5]=sd->status.luk+sd->paramb[5]+sd->parame[5];
+ for(i=0;i<6;i++)
+ if(sd->paramc[i] < 0) sd->paramc[i] = 0;
+
+ if (sd->sc_count) {
+ if (sd->sc_data[SC_CURSE].timer!=-1)
+ sd->paramc[5] = 0;
+ }
+
+ if(sd->status.weapon == 11 || sd->status.weapon == 13 || sd->status.weapon == 14) {
+ str = sd->paramc[4];
+ dex = sd->paramc[0];
+ }
+ else {
+ str = sd->paramc[0];
+ dex = sd->paramc[4];
+ }
+ dstr = str/10;
+ sd->base_atk += str + dstr*dstr + dex/5 + sd->paramc[5]/5;
+ sd->matk1 += sd->paramc[3]+(sd->paramc[3]/5)*(sd->paramc[3]/5);
+ sd->matk2 += sd->paramc[3]+(sd->paramc[3]/7)*(sd->paramc[3]/7);
+ if(sd->matk1 < sd->matk2) {
+ int temp = sd->matk2;
+ sd->matk2 = sd->matk1;
+ sd->matk1 = temp;
+ }
+ sd->hit += sd->paramc[4] + sd->status.base_level;
+ sd->flee += sd->paramc[1] + sd->status.base_level;
+ sd->def2 += sd->paramc[2];
+ sd->mdef2 += sd->paramc[3];
+ sd->flee2 += sd->paramc[5]+10;
+ sd->critical += (sd->paramc[5]*3)+10;
+
+ if(sd->base_atk < 1)
+ sd->base_atk = 1;
+ if(sd->critical_rate != 100)
+ sd->critical = (sd->critical*sd->critical_rate)/100;
+ if(sd->critical < 10) sd->critical = 10;
+ if(sd->hit_rate != 100)
+ sd->hit = (sd->hit*sd->hit_rate)/100;
+ if(sd->hit < 1) sd->hit = 1;
+ if(sd->flee_rate != 100)
+ sd->flee = (sd->flee*sd->flee_rate)/100;
+ if(sd->flee < 1) sd->flee = 1;
+ if(sd->flee2_rate != 100)
+ sd->flee2 = (sd->flee2*sd->flee2_rate)/100;
+ if(sd->flee2 < 10) sd->flee2 = 10;
+ if(sd->def_rate != 100)
+ sd->def = (sd->def*sd->def_rate)/100;
+ if(sd->def < 0) sd->def = 0;
+ if(sd->def2_rate != 100)
+ sd->def2 = (sd->def2*sd->def2_rate)/100;
+ if(sd->def2 < 1) sd->def2 = 1;
+ if(sd->mdef_rate != 100)
+ sd->mdef = (sd->mdef*sd->mdef_rate)/100;
+ if(sd->mdef < 0) sd->mdef = 0;
+ if(sd->mdef2_rate != 100)
+ sd->mdef2 = (sd->mdef2*sd->mdef2_rate)/100;
+ if(sd->mdef2 < 1) sd->mdef2 = 1;
+
+ // “ñ“—¬ ASPD C³
+ if (sd->status.weapon <= 16)
+ sd->aspd += aspd_base[s_class.job][sd->status.weapon]-(sd->paramc[1]*4+sd->paramc[4])*aspd_base[s_class.job][sd->status.weapon]/1000;
+ else
+ sd->aspd += (
+ (aspd_base[s_class.job][sd->weapontype1]-(sd->paramc[1]*4+sd->paramc[4])*aspd_base[s_class.job][sd->weapontype1]/1000) +
+ (aspd_base[s_class.job][sd->weapontype2]-(sd->paramc[1]*4+sd->paramc[4])*aspd_base[s_class.job][sd->weapontype2]/1000)
+ ) * 140 / 200;
+
+ aspd_rate = sd->aspd_rate;
+
+ //U?‘¬“x?‰Á
+
+ if((skill=pc_checkskill(sd,AC_VULTURE))>0){ // ƒƒV‚Ì–Ú
+ sd->hit += skill;
+ if(sd->status.weapon == 11)
+ sd->attackrange += skill;
+ }
+
+ if( (skill=pc_checkskill(sd,BS_WEAPONRESEARCH))>0) // •Ší?‹†‚Ì–½’†—¦?‰Á
+ sd->hit += skill*2;
+ if(sd->status.option&2 && (skill = pc_checkskill(sd,RG_TUNNELDRIVE))>0 ) // ƒgƒ“ƒlƒ‹ƒhƒ‰ƒCƒu // ƒgƒ“ƒlƒ‹ƒhƒ‰ƒCƒu
+ sd->speed += (100-16*skill)*DEFAULT_WALK_SPEED/100;
+ //sd->speed += (1.2*DEFAULT_WALK_SPEED - skill*9);
+ if (pc_iscarton(sd) && (skill=pc_checkskill(sd,MC_PUSHCART))>0) // ƒJ?ƒg‚É‚æ‚鑬“x’ቺ
+ sd->speed += (short) ((10-skill) * (DEFAULT_WALK_SPEED * 0.1));
+ else if (pc_isriding(sd)) { // ƒyƒRƒyƒR?‚è‚É‚æ‚鑬“x?‰Á
+ sd->speed -= (short) ((0.25 * DEFAULT_WALK_SPEED));
+ sd->max_weight += 10000;
+ }
+ if((skill=pc_checkskill(sd,CR_TRUST))>0) { // ƒtƒFƒCƒX
+ sd->status.max_hp += skill*200;
+ sd->subele[6] += skill*5;
+ }
+ if((skill=pc_checkskill(sd,BS_SKINTEMPER))>0) {
+ sd->subele[0] += skill;
+ sd->subele[3] += skill*5;
+ }
+ if((skill=pc_checkskill(sd,SA_ADVANCEDBOOK))>0 )
+ aspd_rate -= (int) (skill*0.5);
+
+ bl=sd->status.base_level;
+
+ sd->status.max_hp += (3500 + bl*hp_coefficient2[s_class.job] + hp_sigma_val[s_class.job][(bl > 0)? bl-1:0])/100 * (100 + sd->paramc[2])/100 + (sd->parame[2] - sd->paramcard[2]);
+ if (s_class.upper==1) // [MouseJstr]
+ sd->status.max_hp = sd->status.max_hp * 130/100;
+ else if (s_class.upper==2)
+ sd->status.max_hp = sd->status.max_hp * 70/100;
+
+ if (sd->hprate <= 0)
+ sd->hprate = 1;
+ if(sd->hprate!=100)
+ sd->status.max_hp = sd->status.max_hp*sd->hprate/100;
+
+ if(sd->sc_count && sd->sc_data[SC_BERSERK].timer!=-1){ // ƒo?ƒT?ƒN
+ sd->status.max_hp = sd->status.max_hp * 3;
+ // sd->status.hp = sd->status.hp * 3;
+ if(sd->status.max_hp > battle_config.max_hp) // removed negative max hp bug by Valaris
+ sd->status.max_hp = battle_config.max_hp;
+ if(sd->status.hp > battle_config.max_hp) // removed negative max hp bug by Valaris
+ sd->status.hp = battle_config.max_hp;
+ }
+ if(s_class.job == 23 && sd->status.base_level >= 99){
+ sd->status.max_hp = sd->status.max_hp + 2000;
+ }
+
+ if(sd->status.max_hp > battle_config.max_hp) // removed negative max hp bug by Valaris
+ sd->status.max_hp = battle_config.max_hp;
+ if(sd->status.max_hp <= 0) sd->status.max_hp = 1; // end
+
+ // Å‘åSPŒvŽZ
+ sd->status.max_sp += ((sp_coefficient[s_class.job] * bl) + 1000)/100 * (100 + sd->paramc[3])/100 + (sd->parame[3] - sd->paramcard[3]);
+ if (s_class.upper==1) // [MouseJstr]
+ sd->status.max_sp = sd->status.max_sp * 130/100;
+ else if (s_class.upper==2)
+ sd->status.max_sp = sd->status.max_sp * 70/100;
+ if (sd->sprate <= 0)
+ sd->sprate = 1;
+ if(sd->sprate!=100)
+ sd->status.max_sp = sd->status.max_sp*sd->sprate/100;
+
+ if((skill=pc_checkskill(sd,HP_MEDITATIO))>0) // ƒƒfƒBƒeƒCƒeƒBƒI
+ sd->status.max_sp += sd->status.max_sp*skill/100;
+ if((skill=pc_checkskill(sd,HW_SOULDRAIN))>0) /* ƒ\ƒEƒ‹ƒhƒŒƒCƒ“ */
+ sd->status.max_sp += sd->status.max_sp*2*skill/100;
+
+ if(sd->status.max_sp < 0 || sd->status.max_sp > battle_config.max_sp)
+ sd->status.max_sp = battle_config.max_sp;
+
+ //Ž©‘R‰ñ•œHP
+ sd->nhealhp = 1 + (sd->paramc[2]/5) + (sd->status.max_hp/200);
+ if((skill=pc_checkskill(sd,SM_RECOVERY)) > 0) { /* HP‰ñ•œ—ÍŒüã */
+ sd->nshealhp = skill*5 + (sd->status.max_hp*skill/500);
+ if(sd->nshealhp > 0x7fff) sd->nshealhp = 0x7fff;
+ }
+ //Ž©‘R‰ñ•œSP
+ sd->nhealsp = 1 + (sd->paramc[3]/6) + (sd->status.max_sp/100);
+ if(sd->paramc[3] >= 120)
+ sd->nhealsp += ((sd->paramc[3]-120)>>1) + 4;
+ if((skill=pc_checkskill(sd,MG_SRECOVERY)) > 0) { /* SP‰ñ•œ—ÍŒüã */
+ sd->nshealsp = skill*3 + (sd->status.max_sp*skill/500);
+ if(sd->nshealsp > 0x7fff) sd->nshealsp = 0x7fff;
+ }
+
+ if((skill = pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0) {
+ sd->nsshealhp = skill*4 + (sd->status.max_hp*skill/500);
+ sd->nsshealsp = skill*2 + (sd->status.max_sp*skill/500);
+ if(sd->nsshealhp > 0x7fff) sd->nsshealhp = 0x7fff;
+ if(sd->nsshealsp > 0x7fff) sd->nsshealsp = 0x7fff;
+ }
+ if(sd->hprecov_rate != 100) {
+ sd->nhealhp = sd->nhealhp*sd->hprecov_rate/100;
+ if(sd->nhealhp < 1) sd->nhealhp = 1;
+ }
+ if(sd->sprecov_rate != 100) {
+ sd->nhealsp = sd->nhealsp*sd->sprecov_rate/100;
+ if(sd->nhealsp < 1) sd->nhealsp = 1;
+ }
+ /* if((skill=pc_checkskill(sd,HP_MEDITATIO)) > 0) { // f?fffBfefCfefBfI,I'SPR,A*,I',E`,¡©Z((c)¡®R¢¶n~.©«,E',(c),(c),e'
+ sd->nhealsp += 3*skill*(sd->status.max_sp)/100;
+ if(sd->nhealsp > 0x7fff) sd->nhealsp = 0x7fff;
+ } Increase natural SP regen instead of colossal SP Recovery effect [DracoRPG]*/
+
+ // Ží‘°‘Ï«i‚±‚ê‚Å‚¢‚¢‚ÌH ƒfƒBƒoƒCƒ“ƒvƒƒeƒNƒVƒ‡ƒ“‚Æ“¯‚¶?—‚ª‚¢‚é‚©‚àj
+ if( (skill=pc_checkskill(sd,SA_DRAGONOLOGY))>0 ){ // ƒhƒ‰ƒSƒmƒƒW?
+ skill = skill*4;
+ sd->addrace[9]+=skill;
+ sd->addrace_[9]+=skill;
+ sd->subrace[9]+=skill;
+ sd->magic_addrace[9]+=skill;
+ sd->magic_subrace[9]-=skill;
+ }
+
+ //Fleeã¸
+ if( (skill=pc_checkskill(sd,TF_MISS))>0 ){ // ‰ñ”ð—¦?‰Á
+ sd->flee += skill*((sd->status.class_==12 || sd->status.class_==17 || sd->status.class_==4013 || sd->status.class_==4018) ? 4 : 3);
+ if((sd->status.class_==12 || sd->status.class_==4013) && (sd->sc_count && sd->sc_data[SC_CLOAKING].timer==-1))
+ sd->speed -= (short)(skill*1.5/100 * DEFAULT_WALK_SPEED);
+ }
+ if( (skill=pc_checkskill(sd,MO_DODGE))>0 ) // Œ©Ø‚è
+ sd->flee += (skill*3)>>1;
+
+ // ƒXƒLƒ‹‚âƒXƒe?ƒ^ƒXˆÙí‚É‚æ‚é?‚è‚̃pƒ‰ƒ?ƒ^•â³
+ if(sd->sc_count){
+ // ATK/DEF?‰»Œ`
+ if(sd->sc_data[SC_ANGELUS].timer!=-1) // ƒGƒ“ƒWƒFƒ‰ƒX
+ sd->def2 = sd->def2*(110+5*sd->sc_data[SC_ANGELUS].val1)/100;
+ if(sd->sc_data[SC_IMPOSITIO].timer!=-1) {// ƒCƒ“ƒ|ƒVƒeƒBƒIƒ}ƒkƒX
+ sd->watk += sd->sc_data[SC_IMPOSITIO].val1*5;
+ index = sd->equip_index[8];
+ if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4)
+ sd->watk_ += sd->sc_data[SC_IMPOSITIO].val1*5;
+ }
+ if(sd->sc_data[SC_PROVOKE].timer!=-1){ // ƒvƒƒ{ƒbƒN
+ sd->def2 = sd->def2*(100-6*sd->sc_data[SC_PROVOKE].val1)/100;
+ sd->base_atk = sd->base_atk*(100+2*sd->sc_data[SC_PROVOKE].val1)/100;
+ sd->watk = sd->watk*(100+2*sd->sc_data[SC_PROVOKE].val1)/100;
+ index = sd->equip_index[8];
+ if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4)
+ sd->watk_ = sd->watk_*(100+2*sd->sc_data[SC_PROVOKE].val1)/100;
+ }
+ if(sd->sc_data[SC_ENDURE].timer!=-1)
+ sd->mdef2 += sd->sc_data[SC_ENDURE].val1;
+ if(sd->sc_data[SC_MINDBREAKER].timer!=-1){ // ƒvƒƒ{ƒbƒN
+ sd->mdef2 = sd->mdef2*(100-6*sd->sc_data[SC_MINDBREAKER].val1)/100;
+ sd->matk1 = sd->matk1*(100+2*sd->sc_data[SC_MINDBREAKER].val1)/100;
+ sd->matk2 = sd->matk2*(100+2*sd->sc_data[SC_MINDBREAKER].val1)/100;
+ }
+ if(sd->sc_data[SC_POISON].timer!=-1) // “Å?‘Ô
+ sd->def2 = sd->def2*75/100;
+ if(sd->sc_data[SC_CURSE].timer!=-1){
+ sd->base_atk = sd->base_atk*75/100;
+ sd->watk = sd->watk*75/100;
+ index = sd->equip_index[8];
+ if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4)
+ sd->watk_ = sd->watk_*75/100;
+ }
+ if(sd->sc_data[SC_DRUMBATTLE].timer!=-1){ // ?‘¾ŒÛ‚Ì‹¿‚«
+ sd->watk += sd->sc_data[SC_DRUMBATTLE].val2;
+ sd->def += sd->sc_data[SC_DRUMBATTLE].val3;
+ index = sd->equip_index[8];
+ if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4)
+ sd->watk_ += sd->sc_data[SC_DRUMBATTLE].val2;
+ }
+ if(sd->sc_data[SC_NIBELUNGEN].timer!=-1) { // ƒj?ƒxƒ‹ƒ“ƒO‚ÌŽw—Ö
+ index = sd->equip_index[9];
+ /*if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 3)
+ sd->watk += sd->sc_data[SC_NIBELUNGEN].val3;
+ index = sd->equip_index[8];
+ if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 3)
+ sd->watk_ += sd->sc_data[SC_NIBELUNGEN].val3;
+ index = sd->equip_index[9];*/
+ if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 4)
+ sd->watk2 += sd->sc_data[SC_NIBELUNGEN].val3;
+ index = sd->equip_index[8];
+ if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 4)
+ sd->watk_2 += sd->sc_data[SC_NIBELUNGEN].val3;
+ }
+
+ if(sd->sc_data[SC_VOLCANO].timer!=-1 && sd->def_ele==3){ // ƒ{ƒ‹ƒP?ƒm
+ sd->watk += sd->sc_data[SC_VOLCANO].val3;
+ }
+
+ if(sd->sc_data[SC_SIGNUMCRUCIS].timer!=-1)
+ sd->def = sd->def * (100 - sd->sc_data[SC_SIGNUMCRUCIS].val2)/100;
+ if(sd->sc_data[SC_ETERNALCHAOS].timer!=-1) // ƒGƒ^?ƒiƒ‹ƒJƒIƒX
+ sd->def=0;
+
+ if(sd->sc_data[SC_CONCENTRATION].timer!=-1){ //ƒRƒ“ƒZƒ“ƒgƒŒ?ƒVƒ‡ƒ“
+ sd->watk = sd->watk * (100 + 5*sd->sc_data[SC_CONCENTRATION].val1)/100;
+ index = sd->equip_index[8];
+ if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4)
+ sd->watk_ = sd->watk * (100 + 5*sd->sc_data[SC_CONCENTRATION].val1)/100;
+ sd->def = sd->def * (100 - 5*sd->sc_data[SC_CONCENTRATION].val1)/100;
+ }
+
+ if(sd->sc_data[SC_MAGICPOWER].timer!=-1){ //–‚–@—Í?•
+ sd->matk1 = sd->matk1*(100+5*sd->sc_data[SC_MAGICPOWER].val1)/100;
+ sd->matk2 = sd->matk2*(100+5*sd->sc_data[SC_MAGICPOWER].val1)/100;
+ }
+ if(sd->sc_data[SC_ATKPOT].timer!=-1)
+ sd->watk += sd->sc_data[SC_ATKPOT].val1;
+ if(sd->sc_data[SC_MATKPOT].timer!=-1){
+ sd->matk1 += sd->sc_data[SC_MATKPOT].val1;
+ sd->matk2 += sd->sc_data[SC_MATKPOT].val1;
+ }
+
+ // ASPD/ˆÚ“®‘¬“x?‰»Œn
+ if(sd->sc_data[SC_TWOHANDQUICKEN].timer != -1 && sd->sc_data[SC_QUAGMIRE].timer == -1 && sd->sc_data[SC_DONTFORGETME].timer == -1) // 2HQ
+ aspd_rate -= 30;
+ if(sd->sc_data[SC_ADRENALINE].timer != -1 && sd->sc_data[SC_TWOHANDQUICKEN].timer == -1 &&
+ sd->sc_data[SC_QUAGMIRE].timer == -1 && sd->sc_data[SC_DONTFORGETME].timer == -1) { // ƒAƒhƒŒƒiƒŠƒ“ƒ‰ƒbƒVƒ…
+ if(sd->sc_data[SC_ADRENALINE].val2 || !battle_config.party_skill_penalty)
+ aspd_rate -= 30;
+ else
+ aspd_rate -= 25;
+ }
+ if(sd->sc_data[SC_SPEARSQUICKEN].timer != -1 && sd->sc_data[SC_ADRENALINE].timer == -1 &&
+ sd->sc_data[SC_TWOHANDQUICKEN].timer == -1 && sd->sc_data[SC_QUAGMIRE].timer == -1 && sd->sc_data[SC_DONTFORGETME].timer == -1) // ƒXƒsƒAƒNƒBƒbƒPƒ“
+ aspd_rate -= sd->sc_data[SC_SPEARSQUICKEN].val2;
+ if(sd->sc_data[SC_ASSNCROS].timer!=-1 && // —[—z‚̃AƒTƒVƒ“ƒNƒƒX
+ sd->sc_data[SC_TWOHANDQUICKEN].timer==-1 && sd->sc_data[SC_ADRENALINE].timer==-1 && sd->sc_data[SC_SPEARSQUICKEN].timer==-1 &&
+ sd->sc_data[SC_DONTFORGETME].timer == -1)
+ aspd_rate -= 5+sd->sc_data[SC_ASSNCROS].val1+sd->sc_data[SC_ASSNCROS].val2+sd->sc_data[SC_ASSNCROS].val3;
+ if(sd->sc_data[SC_DONTFORGETME].timer!=-1){ // Ž„‚ð–Y‚ê‚È‚¢‚Å
+ aspd_rate += sd->sc_data[SC_DONTFORGETME].val1*3 + sd->sc_data[SC_DONTFORGETME].val2 + (sd->sc_data[SC_DONTFORGETME].val3>>16);
+ sd->speed= sd->speed*(100+sd->sc_data[SC_DONTFORGETME].val1*2 + sd->sc_data[SC_DONTFORGETME].val2 + (sd->sc_data[SC_DONTFORGETME].val3&0xffff))/100;
+ }
+ if( sd->sc_data[i=SC_SPEEDPOTION3].timer!=-1 ||
+ sd->sc_data[i=SC_SPEEDPOTION2].timer!=-1 ||
+ sd->sc_data[i=SC_SPEEDPOTION1].timer!=-1 ||
+ sd->sc_data[i=SC_SPEEDPOTION0].timer!=-1) // ? ‘¬ƒ|?ƒVƒ‡ƒ“
+ aspd_rate -= sd->sc_data[i].val2;
+ if(sd->sc_data[SC_WINDWALK].timer!=-1 && sd->sc_data[SC_INCREASEAGI].timer==-1) //ƒEƒBƒ“ƒhƒEƒH?ƒNŽbÍLv*2%Œ¸ŽZ
+ sd->speed -= sd->speed *(sd->sc_data[SC_WINDWALK].val1*2)/100;
+ if(sd->sc_data[SC_CARTBOOST].timer!=-1) // ƒJ?ƒgƒu?ƒXƒg
+ sd->speed -= (DEFAULT_WALK_SPEED * 20)/100;
+ if(sd->sc_data[SC_BERSERK].timer!=-1) //ƒo?ƒT?ƒN’†‚ÍIA‚Æ“¯‚¶‚®‚ç‚¢‘¬‚¢H
+ sd->speed -= sd->speed *25/100;
+ if(sd->sc_data[SC_WEDDING].timer!=-1) //Œ‹¥’†‚Í?‚­‚Ì‚ª?‚¢
+ sd->speed = 2*DEFAULT_WALK_SPEED;
+
+ // HIT/FLEE?‰»Œn
+ if(sd->sc_data[SC_WHISTLE].timer!=-1){ // Œû“J
+ sd->flee += sd->flee * (sd->sc_data[SC_WHISTLE].val1
+ +sd->sc_data[SC_WHISTLE].val2+(sd->sc_data[SC_WHISTLE].val3>>16))/100;
+ sd->flee2+= (sd->sc_data[SC_WHISTLE].val1+sd->sc_data[SC_WHISTLE].val2+(sd->sc_data[SC_WHISTLE].val3&0xffff)) * 10;
+ }
+ if(sd->sc_data[SC_HUMMING].timer!=-1) // ƒnƒ~ƒ“ƒO
+ sd->hit += (sd->sc_data[SC_HUMMING].val1*2+sd->sc_data[SC_HUMMING].val2
+ +sd->sc_data[SC_HUMMING].val3) * sd->hit/100;
+ if(sd->sc_data[SC_VIOLENTGALE].timer!=-1 && sd->def_ele==4){ // ƒoƒCƒIƒŒƒ“ƒgƒQƒCƒ‹
+ sd->flee += sd->flee*sd->sc_data[SC_VIOLENTGALE].val3/100;
+ }
+ if(sd->sc_data[SC_BLIND].timer!=-1){ // ˆÃ?
+ sd->hit -= sd->hit*25/100;
+ sd->flee -= sd->flee*25/100;
+ }
+ if(sd->sc_data[SC_WINDWALK].timer!=-1) // ƒEƒBƒ“ƒhƒEƒH?ƒN
+ sd->flee += sd->flee*(sd->sc_data[SC_WINDWALK].val2)/100;
+ if(sd->sc_data[SC_SPIDERWEB].timer!=-1) //ƒXƒpƒCƒ_?ƒEƒFƒu
+ sd->flee -= sd->flee*50/100;
+ if(sd->sc_data[SC_TRUESIGHT].timer!=-1) //ƒgƒDƒ‹?ƒTƒCƒg
+ sd->hit += 3*(sd->sc_data[SC_TRUESIGHT].val1);
+ if(sd->sc_data[SC_CONCENTRATION].timer!=-1) //ƒRƒ“ƒZƒ“ƒgƒŒ?ƒVƒ‡ƒ“
+ sd->hit += (10*(sd->sc_data[SC_CONCENTRATION].val1));
+
+ // ‘Ï«
+ if(sd->sc_data[SC_SIEGFRIED].timer!=-1){ // •sŽ€g‚̃W?ƒNƒtƒŠ?ƒh
+ sd->subele[1] += sd->sc_data[SC_SIEGFRIED].val2; // …
+ sd->subele[2] += sd->sc_data[SC_SIEGFRIED].val2; // …
+ sd->subele[3] += sd->sc_data[SC_SIEGFRIED].val2; // ‰Î
+ sd->subele[4] += sd->sc_data[SC_SIEGFRIED].val2; // …
+ sd->subele[5] += sd->sc_data[SC_SIEGFRIED].val2; // …
+ sd->subele[6] += sd->sc_data[SC_SIEGFRIED].val2; // …
+ sd->subele[7] += sd->sc_data[SC_SIEGFRIED].val2; // …
+ sd->subele[8] += sd->sc_data[SC_SIEGFRIED].val2; // …
+ sd->subele[9] += sd->sc_data[SC_SIEGFRIED].val2; // …
+ }
+ if(sd->sc_data[SC_PROVIDENCE].timer!=-1){ // ƒvƒƒ”ƒBƒfƒ“ƒX
+ sd->subele[6] += sd->sc_data[SC_PROVIDENCE].val2; // ? ¹?«
+ sd->subrace[6] += sd->sc_data[SC_PROVIDENCE].val2; // ? ?–‚
+ }
+
+ // ‚»‚Ì‘¼
+ if(sd->sc_data[SC_APPLEIDUN].timer!=-1){ // ƒCƒhƒDƒ“‚Ì—ÑŒç
+ sd->status.max_hp += ((5+sd->sc_data[SC_APPLEIDUN].val1*2+((sd->sc_data[SC_APPLEIDUN].val2+1)>>1)
+ +sd->sc_data[SC_APPLEIDUN].val3/10) * sd->status.max_hp)/100;
+ if(sd->status.max_hp < 0 || sd->status.max_hp > battle_config.max_hp)
+ sd->status.max_hp = battle_config.max_hp;
+ }
+ if(sd->sc_data[SC_DELUGE].timer!=-1 && sd->def_ele==1){ // ƒfƒŠƒ…?ƒW
+ sd->status.max_hp += sd->status.max_hp * deluge_eff[sd->sc_data[SC_DELUGE].val1-1]/100;
+ if(sd->status.max_hp < 0 || sd->status.max_hp > battle_config.max_hp)
+ sd->status.max_hp = battle_config.max_hp;
+ }
+ if(sd->sc_data[SC_SERVICE4U].timer!=-1) { // ƒT?ƒrƒXƒtƒH?ƒ†?
+ sd->status.max_sp += sd->status.max_sp*(10+sd->sc_data[SC_SERVICE4U].val1+sd->sc_data[SC_SERVICE4U].val2
+ +sd->sc_data[SC_SERVICE4U].val3)/100;
+ if(sd->status.max_sp < 0 || sd->status.max_sp > battle_config.max_sp)
+ sd->status.max_sp = battle_config.max_sp;
+ sd->dsprate-=(10+sd->sc_data[SC_SERVICE4U].val1*3+sd->sc_data[SC_SERVICE4U].val2
+ +sd->sc_data[SC_SERVICE4U].val3);
+ if(sd->dsprate<0)sd->dsprate=0;
+ }
+
+ if(sd->sc_data[SC_FORTUNE].timer!=-1) // K‰^‚̃LƒX
+ sd->critical += (10+sd->sc_data[SC_FORTUNE].val1+sd->sc_data[SC_FORTUNE].val2
+ +sd->sc_data[SC_FORTUNE].val3)*10;
+
+ if(sd->sc_data[SC_EXPLOSIONSPIRITS].timer!=-1){ // ”š—ô”g“®
+ if(s_class.job==23)
+ sd->critical += sd->sc_data[SC_EXPLOSIONSPIRITS].val1*100;
+ else
+ sd->critical += sd->sc_data[SC_EXPLOSIONSPIRITS].val2;
+ }
+
+ if(sd->sc_data[SC_STEELBODY].timer!=-1){ // ‹à„
+ sd->def = 90;
+ sd->mdef = 90;
+ aspd_rate += 25;
+ sd->speed = (sd->speed * 125) / 100;
+ }
+ if(sd->sc_data[SC_DEFENDER].timer != -1) {
+ //sd->aspd += (550 - sd->sc_data[SC_DEFENDER].val1*50);
+ aspd_rate += (25 - sd->sc_data[SC_DEFENDER].val1*5);
+ sd->speed = (sd->speed * (155 - sd->sc_data[SC_DEFENDER].val1*5)) / 100;
+ }
+ if(sd->sc_data[SC_ENCPOISON].timer != -1)
+ sd->addeff[4] += sd->sc_data[SC_ENCPOISON].val2;
+
+ if( sd->sc_data[SC_DANCING].timer!=-1 ){ // ‰‰‘t/ƒ_ƒ“ƒXŽg—p’†
+ sd->speed = (short) ((double)sd->speed * (6.- 0.4 * pc_checkskill(sd, ((s_class.job == 19) ? BA_MUSICALLESSON : DC_DANCINGLESSON))));
+ //sd->speed*=4;
+ sd->nhealsp = 0;
+ sd->nshealsp = 0;
+ sd->nsshealsp = 0;
+ }
+ if(sd->sc_data[SC_CURSE].timer!=-1)
+ sd->speed += 450;
+
+ if(sd->sc_data[SC_TRUESIGHT].timer!=-1) //ƒgƒDƒ‹?ƒTƒCƒg
+ sd->critical += sd->critical*(sd->sc_data[SC_TRUESIGHT].val1)/100;
+
+/* if(sd->sc_data[SC_VOLCANO].timer!=-1) // ƒGƒ“ƒ`ƒƒƒ“ƒgƒ|ƒCƒYƒ“(?«‚Íbattle.c‚Å)
+ sd->addeff[2]+=sd->sc_data[SC_VOLCANO].val2;//% of granting
+ if(sd->sc_data[SC_DELUGE].timer!=-1) // ƒGƒ“ƒ`ƒƒƒ“ƒgƒ|ƒCƒYƒ“(?«‚Íbattle.c‚Å)
+ sd->addeff[0]+=sd->sc_data[SC_DELUGE].val2;//% of granting
+ */
+ if(sd->sc_data[SC_BERSERK].timer!=-1) { //All Def/MDef reduced to 0 while in Berserk [DracoRPG]
+ sd->def = sd->def2 = 0;
+ sd->mdef = sd->mdef2 = 0;
+ sd->flee -= sd->flee*50/100;
+ aspd_rate -= 30;
+ //sd->base_atk *= 3;
+ }
+ if(sd->sc_data[SC_KEEPING].timer!=-1)
+ sd->def = 100;
+ if(sd->sc_data[SC_BARRIER].timer!=-1)
+ sd->mdef = 100;
+
+ if(sd->sc_data[SC_JOINTBEAT].timer!=-1) { // Random break [DracoRPG]
+ switch(sd->sc_data[SC_JOINTBEAT].val2) {
+ case 1: //Ankle break
+ sd->speed_rate += 50;
+ break;
+ case 2: //Wrist break
+ sd->aspd_rate += 25;
+ break;
+ case 3: //Knee break
+ sd->speed_rate += 30;
+ sd->aspd_rate += 10;
+ break;
+ case 4: //Shoulder break
+ sd->def2 -= sd->def2*50/100;
+ break;
+ case 5: //Waist break
+ sd->def2 -= sd->def2*50/100;
+ sd->base_atk -= sd->base_atk*25/100;
+ break;
+ }
+ }
+
+ if(sd->sc_data[SC_GOSPEL].timer!=-1) {
+ if (sd->sc_data[SC_GOSPEL].val4 == BCT_PARTY){
+ switch (sd->sc_data[SC_GOSPEL].val3)
+ {
+ case 4:
+ sd->status.max_hp += sd->status.max_hp * 25 / 100;
+ if(sd->status.max_hp > battle_config.max_hp)
+ sd->status.max_hp = battle_config.max_hp;
+ break;
+ case 5:
+ sd->status.max_sp += sd->status.max_sp * 25 / 100;
+ if(sd->status.max_sp > battle_config.max_sp)
+ sd->status.max_sp = battle_config.max_sp;
+ break;
+ case 11:
+ sd->def += sd->def * 25 / 100;
+ sd->def2 += sd->def2 * 25 / 100;
+ break;
+ case 12:
+ sd->base_atk += sd->base_atk * 8 / 100;
+ break;
+ case 13:
+ sd->flee += sd->flee * 5 / 100;
+ break;
+ case 14:
+ sd->hit += sd->hit * 5 / 100;
+ break;
+ }
+ } else if (sd->sc_data[SC_GOSPEL].val4 == BCT_ENEMY){
+ switch (sd->sc_data[SC_GOSPEL].val3)
+ {
+ case 5:
+ sd->def = 0;
+ sd->def2 = 0;
+ break;
+ case 6:
+ sd->base_atk = 0;
+ sd->watk = 0;
+ sd->watk2 = 0;
+ break;
+ case 7:
+ sd->flee = 0;
+ break;
+ case 8:
+ sd->speed_rate += 75;
+ aspd_rate += 75;
+ break;
+ }
+ }
+ }
+ // custom stats, since there's no info on how much it actually gives ^^; [Celest]
+ if (sd->sc_data[SC_GUILDAURA].timer != -1) {
+ if (sd->sc_data[SC_GUILDAURA].val4 & 1<<4) {
+ sd->hit += 10;
+ sd->flee += 10;
+ }
+ }
+ }
+
+ if (sd->speed_rate <= 0)
+ sd->speed_rate = 1;
+
+ if(sd->speed_rate != 100)
+ sd->speed = sd->speed*sd->speed_rate/100;
+ if(sd->speed < 1) sd->speed = 1;
+ if(aspd_rate != 100)
+ sd->aspd = sd->aspd*aspd_rate/100;
+ if(pc_isriding(sd)) // ‹R•ºC—û
+ sd->aspd = sd->aspd*(100 + 10*(5 - pc_checkskill(sd,KN_CAVALIERMASTERY)))/ 100;
+ if(sd->aspd < battle_config.max_aspd) sd->aspd = battle_config.max_aspd;
+ sd->amotion = sd->aspd;
+ sd->dmotion = 800-sd->paramc[1]*4;
+ if(sd->dmotion<400)
+ sd->dmotion = 400;
+ if(sd->skilltimer != -1 && (skill = pc_checkskill(sd,SA_FREECAST)) > 0) {
+ sd->prev_speed = sd->speed;
+ sd->speed = sd->speed*(175 - skill*5)/100;
+ }
+
+ if(sd->status.hp>sd->status.max_hp)
+ sd->status.hp=sd->status.max_hp;
+ if(sd->status.sp>sd->status.max_sp)
+ sd->status.sp=sd->status.max_sp;
+
+ if(first&4)
+ return 0;
+ if(first&3) {
+ clif_updatestatus(sd,SP_SPEED);
+ clif_updatestatus(sd,SP_MAXHP);
+ clif_updatestatus(sd,SP_MAXSP);
+ if(first&1) {
+ clif_updatestatus(sd,SP_HP);
+ clif_updatestatus(sd,SP_SP);
+ }
+ return 0;
+ }
+
+ if(b_class != sd->view_class) {
+ clif_changelook(&sd->bl,LOOK_BASE,sd->view_class);
+#if PACKETVER < 4
+ clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
+ clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
+#else
+ clif_changelook(&sd->bl,LOOK_WEAPON,0);
+#endif
+ }
+
+ if( memcmp(b_skill,sd->status.skill,sizeof(sd->status.skill)) || b_attackrange != sd->attackrange)
+ clif_skillinfoblock(sd); // ƒXƒLƒ‹‘—M
+
+ if(b_speed != sd->speed)
+ clif_updatestatus(sd,SP_SPEED);
+ if(b_weight != sd->weight)
+ clif_updatestatus(sd,SP_WEIGHT);
+ if(b_max_weight != sd->max_weight) {
+ clif_updatestatus(sd,SP_MAXWEIGHT);
+ pc_checkweighticon(sd);
+ }
+ for(i=0;i<6;i++)
+ if(b_paramb[i] + b_parame[i] != sd->paramb[i] + sd->parame[i])
+ clif_updatestatus(sd,SP_STR+i);
+ if(b_hit != sd->hit)
+ clif_updatestatus(sd,SP_HIT);
+ if(b_flee != sd->flee)
+ clif_updatestatus(sd,SP_FLEE1);
+ if(b_aspd != sd->aspd)
+ clif_updatestatus(sd,SP_ASPD);
+ if(b_watk != sd->watk || b_base_atk != sd->base_atk)
+ clif_updatestatus(sd,SP_ATK1);
+ if(b_def != sd->def)
+ clif_updatestatus(sd,SP_DEF1);
+ if(b_watk2 != sd->watk2)
+ clif_updatestatus(sd,SP_ATK2);
+ if(b_def2 != sd->def2)
+ clif_updatestatus(sd,SP_DEF2);
+ if(b_flee2 != sd->flee2)
+ clif_updatestatus(sd,SP_FLEE2);
+ if(b_critical != sd->critical)
+ clif_updatestatus(sd,SP_CRITICAL);
+ if(b_matk1 != sd->matk1)
+ clif_updatestatus(sd,SP_MATK1);
+ if(b_matk2 != sd->matk2)
+ clif_updatestatus(sd,SP_MATK2);
+ if(b_mdef != sd->mdef)
+ clif_updatestatus(sd,SP_MDEF1);
+ if(b_mdef2 != sd->mdef2)
+ clif_updatestatus(sd,SP_MDEF2);
+ if(b_attackrange != sd->attackrange)
+ clif_updatestatus(sd,SP_ATTACKRANGE);
+ if(b_max_hp != sd->status.max_hp)
+ clif_updatestatus(sd,SP_MAXHP);
+ if(b_max_sp != sd->status.max_sp)
+ clif_updatestatus(sd,SP_MAXSP);
+ if(b_hp != sd->status.hp)
+ clif_updatestatus(sd,SP_HP);
+ if(b_sp != sd->status.sp)
+ clif_updatestatus(sd,SP_SP);
+
+/* if(before.cart_num != before.cart_num || before.cart_max_num != before.cart_max_num ||
+ before.cart_weight != before.cart_weight || before.cart_max_weight != before.cart_max_weight )
+ clif_updatestatus(sd,SP_CARTINFO);*/
+
+ //if(sd->status.hp<sd->status.max_hp>>2 && pc_checkskill(sd,SM_AUTOBERSERK)>0 &&
+ if(sd->status.hp<sd->status.max_hp>>2 && sd->sc_data[SC_AUTOBERSERK].timer != -1 &&
+ (sd->sc_data[SC_PROVOKE].timer==-1 || sd->sc_data[SC_PROVOKE].val2==0 ) && !pc_isdead(sd))
+ // ƒI?ƒgƒo?ƒT?ƒN?“®
+ status_change_start(&sd->bl,SC_PROVOKE,10,1,0,0,0,0);
+
+ return 0;
+}
+
+/*==========================================
+ * For quick calculating [Celest]
+ *------------------------------------------
+ */
+int status_calc_speed (struct map_session_data *sd)
+{
+ int b_speed, skill;
+ struct pc_base_job s_class;
+
+ nullpo_retr(0, sd);
+
+ s_class = pc_calc_base_job(sd->status.class_);
+
+ b_speed = sd->speed;
+ sd->speed = DEFAULT_WALK_SPEED ;
+
+ if(sd->sc_count){
+ if(sd->sc_data[SC_INCREASEAGI].timer!=-1 && sd->sc_data[SC_QUAGMIRE].timer == -1 && sd->sc_data[SC_DONTFORGETME].timer == -1){ // ‘¬“x?‰Á
+ sd->speed -= sd->speed *25/100;
+ }
+ if(sd->sc_data[SC_DECREASEAGI].timer!=-1) {
+ sd->speed = sd->speed *125/100;
+ }
+ if(sd->sc_data[SC_CLOAKING].timer!=-1) {
+ sd->speed = sd->speed * (sd->sc_data[SC_CLOAKING].val3-sd->sc_data[SC_CLOAKING].val1*3) /100;
+ }
+ if(sd->sc_data[SC_CHASEWALK].timer!=-1) {
+ sd->speed = sd->speed * sd->sc_data[SC_CHASEWALK].val3 /100;
+ }
+ if(sd->sc_data[SC_QUAGMIRE].timer!=-1){
+ sd->speed = sd->speed*3/2;
+ }
+ if(sd->sc_data[SC_WINDWALK].timer!=-1 && sd->sc_data[SC_INCREASEAGI].timer==-1) {
+ sd->speed -= sd->speed *(sd->sc_data[SC_WINDWALK].val1*2)/100;
+ }
+ if(sd->sc_data[SC_CARTBOOST].timer!=-1) {
+ sd->speed -= (DEFAULT_WALK_SPEED * 20)/100;
+ }
+ if(sd->sc_data[SC_BERSERK].timer!=-1) {
+ sd->speed -= sd->speed *25/100;
+ }
+ if(sd->sc_data[SC_WEDDING].timer!=-1) {
+ sd->speed = 2*DEFAULT_WALK_SPEED;
+ }
+ if(sd->sc_data[SC_DONTFORGETME].timer!=-1){
+ sd->speed= sd->speed*(100+sd->sc_data[SC_DONTFORGETME].val1*2 + sd->sc_data[SC_DONTFORGETME].val2 + (sd->sc_data[SC_DONTFORGETME].val3&0xffff))/100;
+ }
+ if(sd->sc_data[SC_STEELBODY].timer!=-1){
+ sd->speed = (sd->speed * 125) / 100;
+ }
+ if(sd->sc_data[SC_DEFENDER].timer != -1) {
+ sd->speed = (sd->speed * (155 - sd->sc_data[SC_DEFENDER].val1*5)) / 100;
+ }
+ if( sd->sc_data[SC_DANCING].timer!=-1 ){
+ sd->speed = (int) ((double)sd->speed * (6.- 0.4 * pc_checkskill(sd, ((s_class.job == 19) ? BA_MUSICALLESSON : DC_DANCINGLESSON))));
+ }
+ if(sd->sc_data[SC_CURSE].timer!=-1)
+ sd->speed += 450;
+ if(sd->sc_data[SC_SLOWDOWN].timer!=-1)
+ sd->speed = sd->speed*150/100;
+ if(sd->sc_data[SC_SPEEDUP0].timer!=-1)
+ sd->speed -= sd->speed*25/100;
+ }
+
+ if(sd->status.option&2 && (skill = pc_checkskill(sd,RG_TUNNELDRIVE))>0 )
+ sd->speed += (100-16*skill)*DEFAULT_WALK_SPEED/100;
+ if (pc_iscarton(sd) && (skill=pc_checkskill(sd,MC_PUSHCART))>0)
+ sd->speed += (short) ((10-skill) * (DEFAULT_WALK_SPEED * 0.1));
+ else if (pc_isriding(sd)) {
+ sd->speed -= (short) ((0.25 * DEFAULT_WALK_SPEED));
+ }
+ if((skill=pc_checkskill(sd,TF_MISS))>0)
+ if(s_class.job==12)
+ sd->speed -= (short) (sd->speed *(skill*1.5)/100);
+
+ if(sd->speed_rate != 100)
+ sd->speed = sd->speed*sd->speed_rate/100;
+ if(sd->speed < 1) sd->speed = 1;
+
+ if(sd->skilltimer != -1 && (skill = pc_checkskill(sd,SA_FREECAST)) > 0) {
+ sd->prev_speed = sd->speed;
+ sd->speed = sd->speed*(175 - skill*5)/100;
+ }
+
+ if(b_speed != sd->speed)
+ clif_updatestatus(sd,SP_SPEED);
+
+ return 0;
+}
+
+/*==========================================
+ * ‘ÎÛ‚ÌClass‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_class(struct block_list *bl)
+{
+ nullpo_retr(0, bl);
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ return ((struct mob_data *)bl)->class_;
+ else if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data *)bl)->status.class_;
+ else if(bl->type==BL_PET && (struct pet_data *)bl)
+ return ((struct pet_data *)bl)->class_;
+ else
+ return 0;
+}
+/*==========================================
+ * ‘ÎÛ‚Ì•ûŒü‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_dir(struct block_list *bl)
+{
+ nullpo_retr(0, bl);
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ return ((struct mob_data *)bl)->dir;
+ else if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data *)bl)->dir;
+ else if(bl->type==BL_PET && (struct pet_data *)bl)
+ return ((struct pet_data *)bl)->dir;
+ else
+ return 0;
+}
+/*==========================================
+ * ‘Îۂ̃Œƒxƒ‹‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_lv(struct block_list *bl)
+{
+ nullpo_retr(0, bl);
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ return ((struct mob_data *)bl)->level;
+ else if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data *)bl)->status.base_level;
+ else if(bl->type==BL_PET && (struct pet_data *)bl)
+ return ((struct pet_data *)bl)->msd->pet.level;
+ else
+ return 0;
+}
+
+/*==========================================
+ * ‘ÎÛ‚ÌŽË’ö‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_range(struct block_list *bl)
+{
+ nullpo_retr(0, bl);
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ return mob_db[((struct mob_data *)bl)->class_].range;
+ else if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data *)bl)->attackrange;
+ else if(bl->type==BL_PET && (struct pet_data *)bl)
+ return mob_db[((struct pet_data *)bl)->class_].range;
+ else
+ return 0;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌHP‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_hp(struct block_list *bl)
+{
+ nullpo_retr(1, bl);
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ return ((struct mob_data *)bl)->hp;
+ else if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data *)bl)->status.hp;
+ else
+ return 1;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌMHP‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_max_hp(struct block_list *bl)
+{
+ nullpo_retr(1, bl);
+
+ if(bl->type==BL_PC && ((struct map_session_data *)bl))
+ return ((struct map_session_data *)bl)->status.max_hp;
+ else {
+ struct status_change *sc_data;
+ int max_hp = 1;
+
+ if(bl->type == BL_MOB) {
+ struct mob_data *md;
+ nullpo_retr(1, md = (struct mob_data *)bl);
+ max_hp = mob_db[md->class_].max_hp;
+
+ if(battle_config.mobs_level_up) // mobs leveling up increase [Valaris]
+ max_hp += (md->level - mob_db[md->class_].lv) * status_get_vit(bl);
+
+ if(mob_db[md->class_].mexp > 0) { //MVP Monsters
+ if(battle_config.mvp_hp_rate != 100) {
+ double hp = (double)max_hp * battle_config.mvp_hp_rate / 100.0;
+ max_hp = (hp > 0x7FFFFFFF ? 0x7FFFFFFF : (int)hp);
+ }
+ }
+ else { //Common MONSTERS
+ if(battle_config.monster_hp_rate != 100) {
+ double hp = (double)max_hp * battle_config.monster_hp_rate / 100.0;
+ max_hp = (hp > 0x7FFFFFFF ? 0x7FFFFFFF : (int)hp);
+ }
+ }
+ }
+ else if(bl->type == BL_PET) {
+ struct pet_data *pd;
+ nullpo_retr(1, pd = (struct pet_data*)bl);
+ max_hp = mob_db[pd->class_].max_hp;
+
+ if(mob_db[pd->class_].mexp > 0) { //MVP Monsters
+ if(battle_config.mvp_hp_rate != 100)
+ max_hp = (max_hp * battle_config.mvp_hp_rate)/100;
+ }
+ else { //Common MONSTERS
+ if(battle_config.monster_hp_rate != 100)
+ max_hp = (max_hp * battle_config.monster_hp_rate)/100;
+ }
+ }
+
+ sc_data = status_get_sc_data(bl);
+ if(sc_data) {
+ if(sc_data[SC_APPLEIDUN].timer != -1)
+ max_hp += ((5 + sc_data[SC_APPLEIDUN].val1 * 2 + ((sc_data[SC_APPLEIDUN].val2 + 1) >> 1)
+ + sc_data[SC_APPLEIDUN].val3 / 10) * max_hp)/100;
+ if(sc_data[SC_GOSPEL].timer != -1 &&
+ sc_data[SC_GOSPEL].val4 == BCT_PARTY &&
+ sc_data[SC_GOSPEL].val3 == 4)
+ max_hp += max_hp * 25 / 100;
+ }
+ if(max_hp < 1) max_hp = 1;
+ return max_hp;
+ }
+ return 1;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌStr‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_str(struct block_list *bl)
+{
+ int str = 0;
+ nullpo_retr(0, bl);
+
+ if (bl->type == BL_PC && ((struct map_session_data *)bl))
+ return ((struct map_session_data *)bl)->paramc[0];
+ else {
+ struct status_change *sc_data;
+ sc_data = status_get_sc_data(bl);
+
+ if(bl->type == BL_MOB && ((struct mob_data *)bl)) {
+ str = mob_db[((struct mob_data *)bl)->class_].str;
+ if(battle_config.mobs_level_up) // mobs leveling up increase [Valaris]
+ str += ((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class_].lv;
+ }
+ else if(bl->type == BL_PET && ((struct pet_data *)bl))
+ str = mob_db[((struct pet_data *)bl)->class_].str;
+
+ if(sc_data) {
+ if(sc_data[SC_LOUD].timer != -1 && sc_data[SC_QUAGMIRE].timer == -1)
+ str += 4;
+ if( sc_data[SC_BLESSING].timer != -1){ // ƒuƒŒƒbƒVƒ“ƒO
+ int race = status_get_race(bl);
+ if(battle_check_undead(race,status_get_elem_type(bl)) || race == 6)
+ str >>= 1; // ˆ« –‚/•sŽ€
+ else str += sc_data[SC_BLESSING].val1; // ‚»‚Ì‘¼
+ }
+ if(sc_data[SC_TRUESIGHT].timer!=-1) // ƒgƒDƒ‹[ƒTƒCƒg
+ str += 5;
+ }
+ }
+ if(str < 0) str = 0;
+ return str;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌAgi‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+
+int status_get_agi(struct block_list *bl)
+{
+ int agi=0;
+ nullpo_retr(0, bl);
+
+ if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data *)bl)->paramc[1];
+ else {
+ struct status_change *sc_data;
+ sc_data = status_get_sc_data(bl);
+ if(bl->type == BL_MOB && (struct mob_data *)bl) {
+ agi = mob_db[((struct mob_data *)bl)->class_].agi;
+ if(battle_config.mobs_level_up) // increase of mobs leveling up [Valaris]
+ agi += ((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class_].lv;
+ }
+ else if(bl->type == BL_PET && (struct pet_data *)bl)
+ agi = mob_db[((struct pet_data *)bl)->class_].agi;
+
+ if(sc_data) {
+ if(sc_data[SC_INCREASEAGI].timer!=-1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) // ‘¬“x‘‰Á(PC‚Ípc.c‚Å)
+ agi += 2 + sc_data[SC_INCREASEAGI].val1;
+ if(sc_data[SC_CONCENTRATE].timer!=-1 && sc_data[SC_QUAGMIRE].timer == -1)
+ agi += agi * (2 + sc_data[SC_CONCENTRATE].val1)/100;
+ if(sc_data[SC_DECREASEAGI].timer!=-1) // ‘¬“xŒ¸­
+ agi -= 2 + sc_data[SC_DECREASEAGI].val1;
+ if(sc_data[SC_QUAGMIRE].timer!=-1 ) { // ƒNƒ@ƒOƒ}ƒCƒA
+ //agi >>= 1;
+ //int agib = agi*(sc_data[SC_QUAGMIRE].val1*10)/100;
+ //agi -= agib > 50 ? 50 : agib;
+ agi -= sc_data[SC_QUAGMIRE].val1*10;
+ }
+ if(sc_data[SC_TRUESIGHT].timer!=-1) // ƒgƒDƒ‹[ƒTƒCƒg
+ agi += 5;
+ }
+ }
+ if(agi < 0) agi = 0;
+ return agi;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌVit‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_vit(struct block_list *bl)
+{
+ int vit = 0;
+ nullpo_retr(0, bl);
+
+ if(bl->type == BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data *)bl)->paramc[2];
+ else {
+ struct status_change *sc_data;
+ sc_data = status_get_sc_data(bl);
+ if(bl->type == BL_MOB && (struct mob_data *)bl) {
+ vit = mob_db[((struct mob_data *)bl)->class_].vit;
+ if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
+ vit += ((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class_].lv;
+ }
+ else if(bl->type == BL_PET && (struct pet_data *)bl)
+ vit = mob_db[((struct pet_data *)bl)->class_].vit;
+ if(sc_data) {
+ if(sc_data[SC_STRIPARMOR].timer != -1)
+ vit = vit*60/100;
+ if(sc_data[SC_TRUESIGHT].timer!=-1) // ƒgƒDƒ‹[ƒTƒCƒg
+ vit += 5;
+ }
+ }
+ if(vit < 0) vit = 0;
+ return vit;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌInt‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_int(struct block_list *bl)
+{
+ int int_=0;
+ nullpo_retr(0, bl);
+
+ if(bl->type == BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data *)bl)->paramc[3];
+ else {
+ struct status_change *sc_data;
+ sc_data = status_get_sc_data(bl);
+ if(bl->type == BL_MOB && (struct mob_data *)bl){
+ int_ = mob_db[((struct mob_data *)bl)->class_].int_;
+ if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
+ int_ += ((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class_].lv;
+ }
+ else if(bl->type == BL_PET && (struct pet_data *)bl)
+ int_ = mob_db[((struct pet_data *)bl)->class_].int_;
+
+ if(sc_data) {
+ if(sc_data[SC_BLESSING].timer != -1){ // ƒuƒŒƒbƒVƒ“ƒO
+ int race = status_get_race(bl);
+ if(battle_check_undead(race,status_get_elem_type(bl)) || race == 6 )
+ int_ >>= 1; // ˆ« –‚/•sŽ€
+ else
+ int_ += sc_data[SC_BLESSING].val1; // ‚»‚Ì‘¼
+ }
+ if(sc_data[SC_STRIPHELM].timer != -1)
+ int_ = int_*60/100;
+ if(sc_data[SC_TRUESIGHT].timer!=-1) // ƒgƒDƒ‹[ƒTƒCƒg
+ int_ += 5;
+ }
+ }
+ if(int_ < 0) int_ = 0;
+ return int_;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌDex‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_dex(struct block_list *bl)
+{
+ int dex = 0;
+ nullpo_retr(0, bl);
+
+ if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data *)bl)->paramc[4];
+ else {
+ struct status_change *sc_data;
+ sc_data = status_get_sc_data(bl);
+ if(bl->type == BL_MOB && (struct mob_data *)bl) {
+ dex = mob_db[((struct mob_data *)bl)->class_].dex;
+ if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
+ dex += ((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class_].lv;
+ }
+ else if(bl->type == BL_PET && (struct pet_data *)bl)
+ dex = mob_db[((struct pet_data *)bl)->class_].dex;
+
+ if(sc_data) {
+ if(sc_data[SC_CONCENTRATE].timer!=-1 && sc_data[SC_QUAGMIRE].timer == -1)
+ dex += dex*(2+sc_data[SC_CONCENTRATE].val1)/100;
+ if(sc_data[SC_BLESSING].timer != -1){ // ƒuƒŒƒbƒVƒ“ƒO
+ int race = status_get_race(bl);
+ if(battle_check_undead(race,status_get_elem_type(bl)) || race == 6 )
+ dex >>= 1; // ˆ« –‚/•sŽ€
+ else dex += sc_data[SC_BLESSING].val1; // ‚»‚Ì‘¼
+ }
+ if(sc_data[SC_QUAGMIRE].timer!=-1) { // ƒNƒ@ƒOƒ}ƒCƒA
+ // dex >>= 1;
+ //int dexb = dex*(sc_data[SC_QUAGMIRE].val1*10)/100;
+ //dex -= dexb > 50 ? 50 : dexb;
+ dex -= sc_data[SC_QUAGMIRE].val1*10;
+ }
+ if(sc_data[SC_TRUESIGHT].timer!=-1) // ƒgƒDƒ‹[ƒTƒCƒg
+ dex += 5;
+ }
+ }
+ if(dex < 0) dex = 0;
+ return dex;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌLuk‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_luk(struct block_list *bl)
+{
+ int luk = 0;
+ nullpo_retr(0, bl);
+
+ if(bl->type == BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data *)bl)->paramc[5];
+ else {
+ struct status_change *sc_data;
+ sc_data = status_get_sc_data(bl);
+ if(bl->type == BL_MOB && (struct mob_data *)bl) {
+ luk = mob_db[((struct mob_data *)bl)->class_].luk;
+ if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
+ luk += ((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class_].lv;
+ }
+ else if(bl->type == BL_PET && (struct pet_data *)bl)
+ luk = mob_db[((struct pet_data *)bl)->class_].luk;
+ if(sc_data) {
+ if(sc_data[SC_GLORIA].timer!=-1) // ƒOƒƒŠƒA(PC‚Ípc.c‚Å)
+ luk += 30;
+ if(sc_data[SC_TRUESIGHT].timer!=-1) // ƒgƒDƒ‹[ƒTƒCƒg
+ luk += 5;
+ if(sc_data[SC_CURSE].timer!=-1) // Žô‚¢
+ luk = 0;
+ }
+ }
+ if(luk < 0) luk = 0;
+ return luk;
+}
+
+/*==========================================
+ * ‘ÎÛ‚ÌFlee‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å1ˆÈã
+ *------------------------------------------
+ */
+int status_get_flee(struct block_list *bl)
+{
+ int flee = 1;
+ nullpo_retr(1, bl);
+
+ if(bl->type == BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data *)bl)->flee;
+ else {
+ struct status_change *sc_data;
+ sc_data = status_get_sc_data(bl);
+ flee = status_get_agi(bl) + status_get_lv(bl);
+
+ if(sc_data){
+ if(sc_data[SC_WHISTLE].timer!=-1)
+ flee += flee*(sc_data[SC_WHISTLE].val1+sc_data[SC_WHISTLE].val2
+ +(sc_data[SC_WHISTLE].val3>>16))/100;
+ if(sc_data[SC_BLIND].timer!=-1)
+ flee -= flee*25/100;
+ if(sc_data[SC_WINDWALK].timer!=-1) // ƒEƒBƒ“ƒhƒEƒH[ƒN
+ flee += flee*(sc_data[SC_WINDWALK].val2)/100;
+ if(sc_data[SC_SPIDERWEB].timer!=-1) //ƒXƒpƒCƒ_[ƒEƒFƒu
+ flee -= flee*50/100;
+ if(sc_data[SC_GOSPEL].timer!=-1) {
+ if (sc_data[SC_GOSPEL].val4 == BCT_PARTY &&
+ sc_data[SC_GOSPEL].val3 == 13)
+ flee += flee*5/100;
+ else if (sc_data[SC_GOSPEL].val4 == BCT_ENEMY &&
+ sc_data[SC_GOSPEL].val3 == 7)
+ flee = 0;
+ }
+ }
+ }
+ if(flee < 1) flee = 1;
+ return flee;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌHit‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å1ˆÈã
+ *------------------------------------------
+ */
+int status_get_hit(struct block_list *bl)
+{
+ int hit = 1;
+ nullpo_retr(1, bl);
+ if(bl->type == BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data *)bl)->hit;
+ else {
+ struct status_change *sc_data;
+ sc_data = status_get_sc_data(bl);
+ hit = status_get_dex(bl) + status_get_lv(bl);
+
+ if(sc_data) {
+ if(sc_data[SC_HUMMING].timer!=-1) //
+ hit += hit*(sc_data[SC_HUMMING].val1*2+sc_data[SC_HUMMING].val2
+ +sc_data[SC_HUMMING].val3)/100;
+ if(sc_data[SC_BLIND].timer!=-1) // Žô‚¢
+ hit -= hit*25/100;
+ if(sc_data[SC_TRUESIGHT].timer!=-1) // ƒgƒDƒ‹[ƒTƒCƒg
+ hit += 3*(sc_data[SC_TRUESIGHT].val1);
+ if(sc_data[SC_CONCENTRATION].timer!=-1) //ƒRƒ“ƒZƒ“ƒgƒŒ[ƒVƒ‡ƒ“
+ hit += (hit*(10*(sc_data[SC_CONCENTRATION].val1)))/100;
+ if(sc_data[SC_GOSPEL].timer!=-1 &&
+ sc_data[SC_GOSPEL].val4 == BCT_PARTY &&
+ sc_data[SC_GOSPEL].val3 == 14)
+ hit += hit*5/100;
+ if(sc_data[SC_EXPLOSIONSPIRITS].timer!=-1)
+ hit += 20*sc_data[SC_EXPLOSIONSPIRITS].val1;
+ }
+ }
+ if(hit < 1) hit = 1;
+ return hit;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌŠ®‘S‰ñ”ð‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å1ˆÈã
+ *------------------------------------------
+ */
+int status_get_flee2(struct block_list *bl)
+{
+ int flee2 = 1;
+ nullpo_retr(1, bl);
+
+ if(bl->type==BL_PC && (struct map_session_data *)bl){
+ return ((struct map_session_data *)bl)->flee2;
+ } else {
+ struct status_change *sc_data;
+ sc_data = status_get_sc_data(bl);
+ flee2 = status_get_luk(bl)+1;
+
+ if(sc_data) {
+ if(sc_data[SC_WHISTLE].timer!=-1)
+ flee2 += (sc_data[SC_WHISTLE].val1+sc_data[SC_WHISTLE].val2
+ +(sc_data[SC_WHISTLE].val3&0xffff))*10;
+ }
+ }
+ if(flee2 < 1) flee2 = 1;
+ return flee2;
+}
+/*==========================================
+ * ‘Îۂ̃NƒŠƒeƒBƒJƒ‹‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å1ˆÈã
+ *------------------------------------------
+ */
+int status_get_critical(struct block_list *bl)
+{
+ int critical = 1;
+ nullpo_retr(1, bl);
+
+ if(bl->type == BL_PC && (struct map_session_data *)bl){
+ return ((struct map_session_data *)bl)->critical;
+ } else {
+ struct status_change *sc_data;
+ sc_data = status_get_sc_data(bl);
+ critical = status_get_luk(bl)*3 + 1;
+
+ if(sc_data) {
+ if(sc_data[SC_FORTUNE].timer!=-1)
+ critical += (10+sc_data[SC_FORTUNE].val1+sc_data[SC_FORTUNE].val2
+ + sc_data[SC_FORTUNE].val3)*10;
+ if(sc_data[SC_EXPLOSIONSPIRITS].timer!=-1)
+ critical += sc_data[SC_EXPLOSIONSPIRITS].val2;
+ if(sc_data[SC_TRUESIGHT].timer!=-1) //ƒgƒDƒ‹[ƒTƒCƒg
+ critical += critical*sc_data[SC_TRUESIGHT].val1/100;
+ }
+ }
+ if(critical < 1) critical = 1;
+ return critical;
+}
+/*==========================================
+ * base_atk‚̎擾
+ * –ß‚è‚Í®”‚Å1ˆÈã
+ *------------------------------------------
+ */
+int status_get_baseatk(struct block_list *bl)
+{
+ int batk = 1;
+ nullpo_retr(1, bl);
+
+ if(bl->type==BL_PC && (struct map_session_data *)bl) {
+ batk = ((struct map_session_data *)bl)->base_atk; //ݒ肳‚ê‚Ä‚¢‚ébase_atk
+ if (((struct map_session_data *)bl)->status.weapon < 16)
+ batk += ((struct map_session_data *)bl)->weapon_atk[((struct map_session_data *)bl)->status.weapon];
+ } else { //‚»‚êˆÈŠO‚È‚ç
+ struct status_change *sc_data;
+ int str,dstr;
+ str = status_get_str(bl); //STR
+ dstr = str/10;
+ batk = dstr*dstr + str; //base_atk‚ðŒvŽZ‚·‚é
+ sc_data = status_get_sc_data(bl);
+
+ if(sc_data) { //ó‘ÔˆÙí‚ ‚è
+ if(sc_data[SC_PROVOKE].timer!=-1) //PC‚Ńvƒƒ{ƒbƒN(SM_PROVOKE)ó‘Ô
+ batk = batk*(100+2*sc_data[SC_PROVOKE].val1)/100; //base_atk‘‰Á
+ if(sc_data[SC_CURSE].timer!=-1) //Žô‚í‚ê‚Ä‚¢‚½‚ç
+ batk -= batk*25/100; //base_atk‚ª25%Œ¸­
+ if(sc_data[SC_CONCENTRATION].timer!=-1) //ƒRƒ“ƒZƒ“ƒgƒŒ[ƒVƒ‡ƒ“
+ batk += batk*(5*sc_data[SC_CONCENTRATION].val1)/100;
+ }
+ }
+ if(batk < 1) batk = 1; //base_atk‚ÍÅ’á‚Å‚à1
+ return batk;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌAtk‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_atk(struct block_list *bl)
+{
+ int atk = 0;
+ nullpo_retr(0, bl);
+
+ if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data*)bl)->watk;
+ else {
+ struct status_change *sc_data;
+ sc_data=status_get_sc_data(bl);
+
+ if(bl->type == BL_MOB && (struct mob_data *)bl)
+ atk = mob_db[((struct mob_data*)bl)->class_].atk1;
+ else if(bl->type == BL_PET && (struct pet_data *)bl)
+ atk = mob_db[((struct pet_data*)bl)->class_].atk1;
+
+ if(sc_data) {
+ if(sc_data[SC_PROVOKE].timer!=-1)
+ atk = atk*(100+2*sc_data[SC_PROVOKE].val1)/100;
+ if(sc_data[SC_CURSE].timer!=-1)
+ atk -= atk*25/100;
+ if(sc_data[SC_CONCENTRATION].timer!=-1) //ƒRƒ“ƒZƒ“ƒgƒŒ[ƒVƒ‡ƒ“
+ atk += atk*(5*sc_data[SC_CONCENTRATION].val1)/100;
+ if(sc_data[SC_EXPLOSIONSPIRITS].timer!=-1)
+ atk += (1000*sc_data[SC_EXPLOSIONSPIRITS].val1);
+ if(sc_data[SC_STRIPWEAPON].timer!=-1)
+ atk -= atk*10/100;
+
+ if(sc_data[SC_GOSPEL].timer!=-1) {
+ if (sc_data[SC_GOSPEL].val4 == BCT_PARTY &&
+ sc_data[SC_GOSPEL].val3 == 12)
+ atk += atk*8/100;
+ else if (sc_data[SC_GOSPEL].val4 == BCT_ENEMY &&
+ sc_data[SC_GOSPEL].val3 == 6)
+ atk = 0;
+ }
+ }
+ }
+ if(atk < 0) atk = 0;
+ return atk;
+}
+/*==========================================
+ * ‘Îۂ̶ŽèAtk‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_atk_(struct block_list *bl)
+{
+ nullpo_retr(0, bl);
+ if(bl->type==BL_PC && (struct map_session_data *)bl){
+ int atk=((struct map_session_data*)bl)->watk_;
+ return atk;
+ }
+ else
+ return 0;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌAtk2‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_atk2(struct block_list *bl)
+{
+ nullpo_retr(0, bl);
+ if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data*)bl)->watk2;
+ else {
+ struct status_change *sc_data=status_get_sc_data(bl);
+ int atk2=0;
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ atk2 = mob_db[((struct mob_data*)bl)->class_].atk2;
+ else if(bl->type==BL_PET && (struct pet_data *)bl)
+ atk2 = mob_db[((struct pet_data*)bl)->class_].atk2;
+ if(sc_data) {
+ if( sc_data[SC_IMPOSITIO].timer!=-1)
+ atk2 += sc_data[SC_IMPOSITIO].val1*5;
+ if( sc_data[SC_PROVOKE].timer!=-1 )
+ atk2 = atk2*(100+2*sc_data[SC_PROVOKE].val1)/100;
+ if( sc_data[SC_CURSE].timer!=-1 )
+ atk2 -= atk2*25/100;
+ if(sc_data[SC_DRUMBATTLE].timer!=-1)
+ atk2 += sc_data[SC_DRUMBATTLE].val2;
+ if(sc_data[SC_NIBELUNGEN].timer!=-1 && (status_get_element(bl)/10) >= 8 )
+ atk2 += sc_data[SC_NIBELUNGEN].val3;
+ if(sc_data[SC_STRIPWEAPON].timer!=-1)
+ atk2 = atk2*sc_data[SC_STRIPWEAPON].val2/100;
+ if(sc_data[SC_CONCENTRATION].timer!=-1) //ƒRƒ“ƒZƒ“ƒgƒŒ[ƒVƒ‡ƒ“
+ atk2 += atk2*(5*sc_data[SC_CONCENTRATION].val1)/100;
+ if(sc_data[SC_EXPLOSIONSPIRITS].timer!=-1)
+ atk2 += (1000*sc_data[SC_EXPLOSIONSPIRITS].val1);
+ }
+ if(atk2 < 0) atk2 = 0;
+ return atk2;
+ }
+ return 0;
+}
+/*==========================================
+ * ‘Îۂ̶ŽèAtk2‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_atk_2(struct block_list *bl)
+{
+ nullpo_retr(0, bl);
+ if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data*)bl)->watk_2;
+ else
+ return 0;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌMAtk1‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_matk1(struct block_list *bl)
+{
+ int matk = 0;
+ nullpo_retr(0, bl);
+
+ if(bl->type == BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data *)bl)->matk1;
+ else {
+ struct status_change *sc_data;
+ int int_ = status_get_int(bl);
+ matk = int_+(int_/5)*(int_/5);
+
+ sc_data = status_get_sc_data(bl);
+ if(sc_data) {
+ if(sc_data[SC_MINDBREAKER].timer!=-1)
+ matk = matk*(100+2*sc_data[SC_MINDBREAKER].val1)/100;
+ }
+ }
+ return matk;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌMAtk2‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_matk2(struct block_list *bl)
+{
+ int matk = 0;
+ nullpo_retr(0, bl);
+
+ if(bl->type == BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data *)bl)->matk2;
+ else {
+ struct status_change *sc_data = status_get_sc_data(bl);
+ int int_ = status_get_int(bl);
+ matk = int_+(int_/7)*(int_/7);
+
+ if(sc_data) {
+ if(sc_data[SC_MINDBREAKER].timer!=-1)
+ matk = matk*(100+2*sc_data[SC_MINDBREAKER].val1)/100;
+ }
+ }
+ return matk;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌDef‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_def(struct block_list *bl)
+{
+ struct status_change *sc_data;
+ int def=0,skilltimer=-1,skillid=0;
+
+ nullpo_retr(0, bl);
+ sc_data=status_get_sc_data(bl);
+ if(bl->type==BL_PC && (struct map_session_data *)bl){
+ def = ((struct map_session_data *)bl)->def;
+ skilltimer = ((struct map_session_data *)bl)->skilltimer;
+ skillid = ((struct map_session_data *)bl)->skillid;
+ }
+ else if(bl->type==BL_MOB && (struct mob_data *)bl) {
+ def = mob_db[((struct mob_data *)bl)->class_].def;
+ skilltimer = ((struct mob_data *)bl)->skilltimer;
+ skillid = ((struct mob_data *)bl)->skillid;
+ }
+ else if(bl->type==BL_PET && (struct pet_data *)bl)
+ def = mob_db[((struct pet_data *)bl)->class_].def;
+
+ if(def < 1000000) {
+ if(sc_data) {
+ //“€Œ‹AΉ»Žž‚͉EƒVƒtƒg
+ if(sc_data[SC_FREEZE].timer != -1 || (sc_data[SC_STONE].timer != -1 && sc_data[SC_STONE].val2 == 0))
+ def >>= 1;
+
+ if (bl->type != BL_PC) {
+ //ƒL[ƒsƒ“ƒOŽž‚ÍDEF100
+ if( sc_data[SC_KEEPING].timer!=-1)
+ def = 100;
+ //ƒvƒƒ{ƒbƒNŽž‚ÍŒ¸ŽZ
+ if( sc_data[SC_PROVOKE].timer!=-1)
+ def = (def*(100 - 6*sc_data[SC_PROVOKE].val1)+50)/100;
+ //푾ŒÛ‚Ì‹¿‚«Žž‚͉ÁŽZ
+ if( sc_data[SC_DRUMBATTLE].timer!=-1)
+ def += sc_data[SC_DRUMBATTLE].val3;
+ //“łɂ©‚©‚Á‚Ä‚¢‚鎞‚ÍŒ¸ŽZ
+ if(sc_data[SC_POISON].timer!=-1)
+ def = def*75/100;
+ //ƒXƒgƒŠƒbƒvƒV[ƒ‹ƒhŽž‚ÍŒ¸ŽZ
+ if(sc_data[SC_STRIPSHIELD].timer!=-1)
+ def = def*sc_data[SC_STRIPSHIELD].val2/100;
+ //ƒVƒOƒiƒ€ƒNƒ‹ƒVƒXŽž‚ÍŒ¸ŽZ
+ if(sc_data[SC_SIGNUMCRUCIS].timer!=-1)
+ def = def * (100 - sc_data[SC_SIGNUMCRUCIS].val2)/100;
+ //‰i‰“‚̬“׎ž‚ÍDEF0‚ɂȂé
+ if(sc_data[SC_ETERNALCHAOS].timer!=-1)
+ def = 0;
+ //ƒRƒ“ƒZƒ“ƒgƒŒ[ƒVƒ‡ƒ“Žž‚ÍŒ¸ŽZ
+ if( sc_data[SC_CONCENTRATION].timer!=-1)
+ def = (def*(100 - 5*sc_data[SC_CONCENTRATION].val1))/100;
+
+ if(sc_data[SC_GOSPEL].timer!=-1) {
+ if (sc_data[SC_GOSPEL].val4 == BCT_PARTY &&
+ sc_data[SC_GOSPEL].val3 == 11)
+ def += def*25/100;
+ else if (sc_data[SC_GOSPEL].val4 == BCT_ENEMY &&
+ sc_data[SC_GOSPEL].val3 == 5)
+ def = 0;
+ }
+ if(sc_data[SC_JOINTBEAT].timer!=-1) {
+ if (sc_data[SC_JOINTBEAT].val2 == 4)
+ def -= def*50/100;
+ else if (sc_data[SC_JOINTBEAT].val2 == 5)
+ def -= def*25/100;
+ }
+ }
+ }
+ //‰r¥’†‚͉r¥ŽžŒ¸ŽZ—¦‚ÉŠî‚¢‚ÄŒ¸ŽZ
+ if(skilltimer != -1) {
+ int def_rate = skill_get_castdef(skillid);
+ if(def_rate != 0)
+ def = (def * (100 - def_rate))/100;
+ }
+ }
+ if(def < 0) def = 0;
+ return def;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌMDef‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_mdef(struct block_list *bl)
+{
+ struct status_change *sc_data;
+ int mdef=0;
+
+ nullpo_retr(0, bl);
+ sc_data=status_get_sc_data(bl);
+ if(bl->type==BL_PC && (struct map_session_data *)bl)
+ mdef = ((struct map_session_data *)bl)->mdef;
+ else if(bl->type==BL_MOB && (struct mob_data *)bl)
+ mdef = mob_db[((struct mob_data *)bl)->class_].mdef;
+ else if(bl->type==BL_PET && (struct pet_data *)bl)
+ mdef = mob_db[((struct pet_data *)bl)->class_].mdef;
+
+ if(mdef < 1000000) {
+ if(sc_data) {
+ //ƒoƒŠƒA[ó‘ÔŽž‚ÍMDEF100
+ if(sc_data[SC_BARRIER].timer != -1)
+ mdef = 100;
+ //“€Œ‹AΉ»Žž‚Í1.25”{
+ if(sc_data[SC_FREEZE].timer != -1 || (sc_data[SC_STONE].timer != -1 && sc_data[SC_STONE].val2 == 0))
+ mdef = mdef*125/100;
+ if( sc_data[SC_MINDBREAKER].timer!=-1 && bl->type != BL_PC)
+ mdef -= (mdef*6*sc_data[SC_MINDBREAKER].val1)/100;
+ }
+ }
+ if(mdef < 0) mdef = 0;
+ return mdef;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌDef2‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å1ˆÈã
+ *------------------------------------------
+ */
+int status_get_def2(struct block_list *bl)
+{
+ int def2 = 1;
+ nullpo_retr(1, bl);
+
+ if(bl->type==BL_PC)
+ return ((struct map_session_data *)bl)->def2;
+ else {
+ struct status_change *sc_data;
+
+ if(bl->type==BL_MOB)
+ def2 = mob_db[((struct mob_data *)bl)->class_].vit;
+ else if(bl->type==BL_PET)
+ def2 = mob_db[((struct pet_data *)bl)->class_].vit;
+
+ sc_data = status_get_sc_data(bl);
+ if(sc_data) {
+ if(sc_data[SC_ANGELUS].timer != -1)
+ def2 = def2*(110+5*sc_data[SC_ANGELUS].val1)/100;
+ if(sc_data[SC_PROVOKE].timer!=-1)
+ def2 = (def2*(100 - 6*sc_data[SC_PROVOKE].val1)+50)/100;
+ if(sc_data[SC_POISON].timer!=-1)
+ def2 = def2*75/100;
+ //ƒRƒ“ƒZƒ“ƒgƒŒ[ƒVƒ‡ƒ“Žž‚ÍŒ¸ŽZ
+ if( sc_data[SC_CONCENTRATION].timer!=-1)
+ def2 = def2*(100 - 5*sc_data[SC_CONCENTRATION].val1)/100;
+
+ if(sc_data[SC_GOSPEL].timer!=-1) {
+ if (sc_data[SC_GOSPEL].val4 == BCT_PARTY &&
+ sc_data[SC_GOSPEL].val3 == 11)
+ def2 += def2*25/100;
+ else if (sc_data[SC_GOSPEL].val4 == BCT_ENEMY &&
+ sc_data[SC_GOSPEL].val3 == 5)
+ def2 = 0;
+ }
+ }
+ }
+ if(def2 < 1) def2 = 1;
+ return def2;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌMDef2‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å0ˆÈã
+ *------------------------------------------
+ */
+int status_get_mdef2(struct block_list *bl)
+{
+ int mdef2 = 0;
+ nullpo_retr(0, bl);
+
+ if(bl->type == BL_PC)
+ return ((struct map_session_data *)bl)->mdef2 + (((struct map_session_data *)bl)->paramc[2]>>1);
+ else {
+ struct status_change *sc_data = status_get_sc_data(bl);
+ if(bl->type == BL_MOB)
+ mdef2 = mob_db[((struct mob_data *)bl)->class_].int_ + (mob_db[((struct mob_data *)bl)->class_].vit>>1);
+ else if(bl->type == BL_PET)
+ mdef2 = mob_db[((struct pet_data *)bl)->class_].int_ + (mob_db[((struct pet_data *)bl)->class_].vit>>1);
+ if(sc_data) {
+ if(sc_data[SC_MINDBREAKER].timer!=-1)
+ mdef2 -= (mdef2*6*sc_data[SC_MINDBREAKER].val1)/100;
+ }
+ }
+ if(mdef2 < 0) mdef2 = 0;
+ return mdef2;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌSpeed(ˆÚ“®‘¬“x)‚ð•Ô‚·(”Ä—p)
+ * –ß‚è‚Í®”‚Å1ˆÈã
+ * Speed‚ͬ‚³‚¢‚Ù‚¤‚ªˆÚ“®‘¬“x‚ª‘¬‚¢
+ *------------------------------------------
+ */
+int status_get_speed(struct block_list *bl)
+{
+ nullpo_retr(1000, bl);
+ if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data *)bl)->speed;
+ else {
+ struct status_change *sc_data=status_get_sc_data(bl);
+ int speed = 1000;
+ if(bl->type==BL_MOB && (struct mob_data *)bl) {
+ speed = ((struct mob_data *)bl)->speed;
+ if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
+ speed-=((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class_].lv;
+ }
+ else if(bl->type==BL_PET && (struct pet_data *)bl)
+ speed = ((struct pet_data *)bl)->msd->petDB->speed;
+
+ if(sc_data) {
+ //‘¬“x‘‰ÁŽž‚Í25%Œ¸ŽZ
+ if(sc_data[SC_INCREASEAGI].timer!=-1)
+ speed -= speed*25/100;
+ //ƒEƒBƒ“ƒhƒEƒH[ƒNŽž‚ÍLv*2%Œ¸ŽZ
+ else if(sc_data[SC_WINDWALK].timer!=-1)
+ speed -= (speed*(sc_data[SC_WINDWALK].val1*2))/100;
+ //‘¬“xŒ¸­Žž‚Í25%‰ÁŽZ
+ if(sc_data[SC_DECREASEAGI].timer!=-1)
+ speed = speed*125/100;
+ //ƒNƒ@ƒOƒ}ƒCƒAŽž‚Í50%‰ÁŽZ
+ if(sc_data[SC_QUAGMIRE].timer!=-1)
+ speed = speed*3/2;
+ //Ž„‚ð–Y‚ê‚È‚¢‚ÅcŽž‚͉ÁŽZ
+ if(sc_data[SC_DONTFORGETME].timer!=-1)
+ speed = speed*(100+sc_data[SC_DONTFORGETME].val1*2 + sc_data[SC_DONTFORGETME].val2 + (sc_data[SC_DONTFORGETME].val3&0xffff))/100;
+ //‹à„Žž‚Í25%‰ÁŽZ
+ if(sc_data[SC_STEELBODY].timer!=-1)
+ speed = speed*125/100;
+ //ƒfƒBƒtƒFƒ“ƒ_[Žž‚͉ÁŽZ
+ if(sc_data[SC_DEFENDER].timer!=-1)
+ speed = (speed * (155 - sc_data[SC_DEFENDER].val1*5)) / 100;
+ //—x‚èó‘Ô‚Í4”{’x‚¢
+ if(sc_data[SC_DANCING].timer!=-1 )
+ speed *= 6;
+ //Žô‚¢Žž‚Í450‰ÁŽZ
+ if(sc_data[SC_CURSE].timer!=-1)
+ speed = speed + 450;
+ if(sc_data[SC_SLOWDOWN].timer!=-1)
+ speed = speed*150/100;
+ if(sc_data[SC_SPEEDUP0].timer!=-1)
+ speed -= speed*25/100;
+ if(sc_data[SC_GOSPEL].timer!=-1 &&
+ sc_data[SC_GOSPEL].val4 == BCT_ENEMY &&
+ sc_data[SC_GOSPEL].val3 == 8)
+ speed = speed*125/100;
+ if(sc_data[SC_JOINTBEAT].timer!=-1) {
+ if (sc_data[SC_JOINTBEAT].val2 == 1)
+ speed = speed*150/100;
+ else if (sc_data[SC_JOINTBEAT].val2 == 3)
+ speed = speed*130/100;
+ }
+ }
+ if(speed < 1) speed = 1;
+ return speed;
+ }
+
+ return 1000;
+}
+/*==========================================
+ * ‘ÎÛ‚ÌaDelay(UŒ‚ŽžƒfƒBƒŒƒC)‚ð•Ô‚·(”Ä—p)
+ * aDelay‚ͬ‚³‚¢‚Ù‚¤‚ªUŒ‚‘¬“x‚ª‘¬‚¢
+ *------------------------------------------
+ */
+int status_get_adelay(struct block_list *bl)
+{
+ nullpo_retr(4000, bl);
+ if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return (((struct map_session_data *)bl)->aspd<<1);
+ else {
+ struct status_change *sc_data=status_get_sc_data(bl);
+ int adelay=4000,aspd_rate = 100,i;
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ adelay = mob_db[((struct mob_data *)bl)->class_].adelay;
+ else if(bl->type==BL_PET && (struct pet_data *)bl)
+ adelay = mob_db[((struct pet_data *)bl)->class_].adelay;
+
+ if(sc_data) {
+ //ƒc[ƒnƒ“ƒhƒNƒCƒbƒPƒ“Žg—pŽž‚ŃNƒ@ƒOƒ}ƒCƒA‚Å‚àŽ„‚ð–Y‚ê‚È‚¢‚Åc‚Å‚à‚È‚¢Žž‚Í3Š„Œ¸ŽZ
+ if(sc_data[SC_TWOHANDQUICKEN].timer != -1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) // 2HQ
+ aspd_rate -= 30;
+ //ƒAƒhƒŒƒiƒŠƒ“ƒ‰ƒbƒVƒ…Žg—pŽž‚Ńc[ƒnƒ“ƒhƒNƒCƒbƒPƒ“‚Å‚àƒNƒ@ƒOƒ}ƒCƒA‚Å‚àŽ„‚ð–Y‚ê‚È‚¢‚Åc‚Å‚à‚È‚¢Žž‚Í
+ if(sc_data[SC_ADRENALINE].timer != -1 && sc_data[SC_TWOHANDQUICKEN].timer == -1 &&
+ sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) { // ƒAƒhƒŒƒiƒŠƒ“ƒ‰ƒbƒVƒ…
+ //Žg—pŽÒ‚ƃp[ƒeƒBƒƒ“ƒo[‚ÅŠi·‚ªo‚éÝ’è‚łȂ¯‚ê‚Î3Š„Œ¸ŽZ
+ if(sc_data[SC_ADRENALINE].val2 || !battle_config.party_skill_penalty)
+ aspd_rate -= 30;
+ //‚»‚¤‚łȂ¯‚ê‚Î2.5Š„Œ¸ŽZ
+ else
+ aspd_rate -= 25;
+ }
+ //ƒXƒsƒAƒNƒBƒbƒPƒ“Žž‚ÍŒ¸ŽZ
+ if(sc_data[SC_SPEARSQUICKEN].timer != -1 && sc_data[SC_ADRENALINE].timer == -1 &&
+ sc_data[SC_TWOHANDQUICKEN].timer == -1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) // ƒXƒsƒAƒNƒBƒbƒPƒ“
+ aspd_rate -= sc_data[SC_SPEARSQUICKEN].val2;
+ //—[“ú‚̃AƒTƒVƒ“ƒNƒƒXŽž‚ÍŒ¸ŽZ
+ if(sc_data[SC_ASSNCROS].timer!=-1 && // —[—z‚̃AƒTƒVƒ“ƒNƒƒX
+ sc_data[SC_TWOHANDQUICKEN].timer==-1 && sc_data[SC_ADRENALINE].timer==-1 && sc_data[SC_SPEARSQUICKEN].timer==-1 &&
+ sc_data[SC_DONTFORGETME].timer == -1)
+ aspd_rate -= 5+sc_data[SC_ASSNCROS].val1+sc_data[SC_ASSNCROS].val2+sc_data[SC_ASSNCROS].val3;
+ //Ž„‚ð–Y‚ê‚È‚¢‚ÅcŽž‚͉ÁŽZ
+ if(sc_data[SC_DONTFORGETME].timer!=-1) // Ž„‚ð–Y‚ê‚È‚¢‚Å
+ aspd_rate += sc_data[SC_DONTFORGETME].val1*3 + sc_data[SC_DONTFORGETME].val2 + (sc_data[SC_DONTFORGETME].val3>>16);
+ //‹à„Žž25%‰ÁŽZ
+ if(sc_data[SC_STEELBODY].timer!=-1) // ‹à„
+ aspd_rate += 25;
+ //‘‘¬ƒ|[ƒVƒ‡ƒ“Žg—pŽž‚ÍŒ¸ŽZ
+ if( sc_data[i=SC_SPEEDPOTION3].timer!=-1 || sc_data[i=SC_SPEEDPOTION2].timer!=-1 || sc_data[i=SC_SPEEDPOTION1].timer!=-1 || sc_data[i=SC_SPEEDPOTION0].timer!=-1)
+ aspd_rate -= sc_data[i].val2;
+ //ƒfƒBƒtƒFƒ“ƒ_[Žž‚͉ÁŽZ
+ if(sc_data[SC_DEFENDER].timer != -1)
+ aspd_rate += (25 - sc_data[SC_DEFENDER].val1*5);
+ //adelay += (1100 - sc_data[SC_DEFENDER].val1*100);
+ if(sc_data[SC_GOSPEL].timer!=-1 &&
+ sc_data[SC_GOSPEL].val4 == BCT_ENEMY &&
+ sc_data[SC_GOSPEL].val3 == 8)
+ aspd_rate = aspd_rate*125/100;
+ if(sc_data[SC_JOINTBEAT].timer!=-1) {
+ if (sc_data[SC_JOINTBEAT].val2 == 2)
+ aspd_rate = aspd_rate*125/100;
+ else if (sc_data[SC_JOINTBEAT].val2 == 3)
+ aspd_rate = aspd_rate*110/100;
+ }
+ }
+ if(aspd_rate != 100)
+ adelay = adelay*aspd_rate/100;
+ if(adelay < battle_config.monster_max_aspd<<1) adelay = battle_config.monster_max_aspd<<1;
+ return adelay;
+ }
+ return 4000;
+}
+int status_get_amotion(struct block_list *bl)
+{
+ nullpo_retr(2000, bl);
+ if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data *)bl)->amotion;
+ else {
+ struct status_change *sc_data=status_get_sc_data(bl);
+ int amotion=2000,aspd_rate = 100,i;
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ amotion = mob_db[((struct mob_data *)bl)->class_].amotion;
+ else if(bl->type==BL_PET && (struct pet_data *)bl)
+ amotion = mob_db[((struct pet_data *)bl)->class_].amotion;
+
+ if(sc_data) {
+ if(sc_data[SC_TWOHANDQUICKEN].timer != -1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) // 2HQ
+ aspd_rate -= 30;
+ if(sc_data[SC_ADRENALINE].timer != -1 && sc_data[SC_TWOHANDQUICKEN].timer == -1 &&
+ sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) { // ƒAƒhƒŒƒiƒŠƒ“ƒ‰ƒbƒVƒ…
+ if(sc_data[SC_ADRENALINE].val2 || !battle_config.party_skill_penalty)
+ aspd_rate -= 30;
+ else
+ aspd_rate -= 25;
+ }
+ if(sc_data[SC_SPEARSQUICKEN].timer != -1 && sc_data[SC_ADRENALINE].timer == -1 &&
+ sc_data[SC_TWOHANDQUICKEN].timer == -1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) // ƒXƒsƒAƒNƒBƒbƒPƒ“
+ aspd_rate -= sc_data[SC_SPEARSQUICKEN].val2;
+ if(sc_data[SC_ASSNCROS].timer!=-1 && // —[—z‚̃AƒTƒVƒ“ƒNƒƒX
+ sc_data[SC_TWOHANDQUICKEN].timer==-1 && sc_data[SC_ADRENALINE].timer==-1 && sc_data[SC_SPEARSQUICKEN].timer==-1 &&
+ sc_data[SC_DONTFORGETME].timer == -1)
+ aspd_rate -= 5+sc_data[SC_ASSNCROS].val1+sc_data[SC_ASSNCROS].val2+sc_data[SC_ASSNCROS].val3;
+ if(sc_data[SC_DONTFORGETME].timer!=-1) // Ž„‚ð–Y‚ê‚È‚¢‚Å
+ aspd_rate += sc_data[SC_DONTFORGETME].val1*3 + sc_data[SC_DONTFORGETME].val2 + (sc_data[SC_DONTFORGETME].val3>>16);
+ if(sc_data[SC_STEELBODY].timer!=-1) // ‹à„
+ aspd_rate += 25;
+ if( sc_data[i=SC_SPEEDPOTION3].timer!=-1 || sc_data[i=SC_SPEEDPOTION2].timer!=-1 || sc_data[i=SC_SPEEDPOTION1].timer!=-1 || sc_data[i=SC_SPEEDPOTION0].timer!=-1)
+ aspd_rate -= sc_data[i].val2;
+ if(sc_data[SC_DEFENDER].timer != -1)
+ aspd_rate += (25 - sc_data[SC_DEFENDER].val1*5);
+ //amotion += (550 - sc_data[SC_DEFENDER].val1*50);
+ }
+ if(aspd_rate != 100)
+ amotion = amotion*aspd_rate/100;
+ if(amotion < battle_config.monster_max_aspd) amotion = battle_config.monster_max_aspd;
+ return amotion;
+ }
+ return 2000;
+}
+int status_get_dmotion(struct block_list *bl)
+{
+ int ret;
+ struct status_change *sc_data;
+
+ nullpo_retr(0, bl);
+ sc_data = status_get_sc_data(bl);
+ if(bl->type==BL_MOB && (struct mob_data *)bl){
+ ret=mob_db[((struct mob_data *)bl)->class_].dmotion;
+ if(battle_config.monster_damage_delay_rate != 100)
+ ret = ret*battle_config.monster_damage_delay_rate/400;
+ }
+ else if(bl->type==BL_PC && (struct map_session_data *)bl){
+ ret=((struct map_session_data *)bl)->dmotion;
+ if(battle_config.pc_damage_delay_rate != 100)
+ ret = ret*battle_config.pc_damage_delay_rate/400;
+ }
+ else if(bl->type==BL_PET && (struct pet_data *)bl)
+ ret=mob_db[((struct pet_data *)bl)->class_].dmotion;
+ else
+ return 2000;
+
+ if((sc_data && (sc_data[SC_ENDURE].timer!=-1 || sc_data[SC_BERSERK].timer!=-1)) ||
+ (bl->type == BL_PC && ((struct map_session_data *)bl)->special_state.infinite_endure))
+ ret=0;
+
+ return ret;
+}
+int status_get_element(struct block_list *bl)
+{
+ int ret = 20;
+ struct status_change *sc_data;
+
+ nullpo_retr(ret, bl);
+ sc_data = status_get_sc_data(bl);
+ if(bl->type==BL_MOB && (struct mob_data *)bl) // 10‚̈ÊLv*2A‚P‚̈ʑ®«
+ ret=((struct mob_data *)bl)->def_ele;
+ else if(bl->type==BL_PC && (struct map_session_data *)bl)
+ ret=20+((struct map_session_data *)bl)->def_ele; // –hŒä‘®«Lv1
+ else if(bl->type==BL_PET && (struct pet_data *)bl)
+ ret = mob_db[((struct pet_data *)bl)->class_].element;
+
+ if(sc_data) {
+ if( sc_data[SC_BENEDICTIO].timer!=-1 ) // ¹‘Ì~•Ÿ
+ ret=26;
+ if( sc_data[SC_FREEZE].timer!=-1 ) // “€Œ‹
+ ret=21;
+ if( sc_data[SC_STONE].timer!=-1 && sc_data[SC_STONE].val2==0)
+ ret=22;
+ }
+
+ return ret;
+}
+
+int status_get_attack_element(struct block_list *bl)
+{
+ int ret = 0;
+ struct status_change *sc_data=status_get_sc_data(bl);
+
+ nullpo_retr(0, bl);
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ ret=0;
+ else if(bl->type==BL_PC && (struct map_session_data *)bl)
+ ret=((struct map_session_data *)bl)->atk_ele;
+ else if(bl->type==BL_PET && (struct pet_data *)bl)
+ ret=0;
+
+ if(sc_data) {
+ if( sc_data[SC_FROSTWEAPON].timer!=-1) // ƒtƒƒXƒgƒEƒFƒ|ƒ“
+ ret=1;
+ if( sc_data[SC_SEISMICWEAPON].timer!=-1) // ƒTƒCƒYƒ~ƒbƒNƒEƒFƒ|ƒ“
+ ret=2;
+ if( sc_data[SC_FLAMELAUNCHER].timer!=-1) // ƒtƒŒ[ƒ€ƒ‰ƒ“ƒ`ƒƒ[
+ ret=3;
+ if( sc_data[SC_LIGHTNINGLOADER].timer!=-1) // ƒ‰ƒCƒgƒjƒ“ƒOƒ[ƒ_[
+ ret=4;
+ if( sc_data[SC_ENCPOISON].timer!=-1) // ƒGƒ“ƒ`ƒƒƒ“ƒgƒ|ƒCƒYƒ“
+ ret=5;
+ if( sc_data[SC_ASPERSIO].timer!=-1) // ƒAƒXƒyƒ‹ƒVƒI
+ ret=6;
+ }
+
+ return ret;
+}
+int status_get_attack_element2(struct block_list *bl)
+{
+ nullpo_retr(0, bl);
+ if(bl->type==BL_PC && (struct map_session_data *)bl) {
+ int ret = ((struct map_session_data *)bl)->atk_ele_;
+ struct status_change *sc_data = ((struct map_session_data *)bl)->sc_data;
+
+ if(sc_data) {
+ if( sc_data[SC_FROSTWEAPON].timer!=-1) // ƒtƒƒXƒgƒEƒFƒ|ƒ“
+ ret=1;
+ if( sc_data[SC_SEISMICWEAPON].timer!=-1) // ƒTƒCƒYƒ~ƒbƒNƒEƒFƒ|ƒ“
+ ret=2;
+ if( sc_data[SC_FLAMELAUNCHER].timer!=-1) // ƒtƒŒ[ƒ€ƒ‰ƒ“ƒ`ƒƒ[
+ ret=3;
+ if( sc_data[SC_LIGHTNINGLOADER].timer!=-1) // ƒ‰ƒCƒgƒjƒ“ƒOƒ[ƒ_[
+ ret=4;
+ if( sc_data[SC_ENCPOISON].timer!=-1) // ƒGƒ“ƒ`ƒƒƒ“ƒgƒ|ƒCƒYƒ“
+ ret=5;
+ if( sc_data[SC_ASPERSIO].timer!=-1) // ƒAƒXƒyƒ‹ƒVƒI
+ ret=6;
+ }
+ return ret;
+ }
+ return 0;
+}
+int status_get_party_id(struct block_list *bl)
+{
+ nullpo_retr(0, bl);
+ if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data *)bl)->status.party_id;
+ else if(bl->type==BL_MOB && (struct mob_data *)bl){
+ struct mob_data *md=(struct mob_data *)bl;
+ if( md->master_id>0 )
+ return -md->master_id;
+ return -md->bl.id;
+ }
+ else if(bl->type==BL_SKILL && (struct skill_unit *)bl)
+ return ((struct skill_unit *)bl)->group->party_id;
+ else
+ return 0;
+}
+int status_get_guild_id(struct block_list *bl)
+{
+ nullpo_retr(0, bl);
+ if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data *)bl)->status.guild_id;
+ else if(bl->type==BL_MOB && (struct mob_data *)bl)
+ return ((struct mob_data *)bl)->class_;
+ else if(bl->type==BL_SKILL && (struct skill_unit *)bl)
+ return ((struct skill_unit *)bl)->group->guild_id;
+ else
+ return 0;
+}
+int status_get_race(struct block_list *bl)
+{
+ nullpo_retr(0, bl);
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ return mob_db[((struct mob_data *)bl)->class_].race;
+ else if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return 7;
+ else if(bl->type==BL_PET && (struct pet_data *)bl)
+ return mob_db[((struct pet_data *)bl)->class_].race;
+ else
+ return 0;
+}
+int status_get_size(struct block_list *bl)
+{
+ nullpo_retr(1, bl);
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ return mob_db[((struct mob_data *)bl)->class_].size;
+ else if(bl->type==BL_PET && (struct pet_data *)bl)
+ return mob_db[((struct pet_data *)bl)->class_].size;
+ else if(bl->type==BL_PC) {
+ struct map_session_data *sd = (struct map_session_data *)bl;
+ //if (pc_isriding(sd)) // fact or rumour?
+ // return 2;
+ if (pc_calc_upper(sd->status.class_) == 2)
+ return 0;
+ return 1;
+ } else
+ return 1;
+}
+int status_get_mode(struct block_list *bl)
+{
+ nullpo_retr(0x01, bl);
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ return mob_db[((struct mob_data *)bl)->class_].mode;
+ else if(bl->type==BL_PET && (struct pet_data *)bl)
+ return mob_db[((struct pet_data *)bl)->class_].mode;
+ else
+ return 0x01; // ‚Ƃ肠‚¦‚¸“®‚­‚Æ‚¢‚¤‚±‚Æ‚Å1
+}
+
+int status_get_mexp(struct block_list *bl)
+{
+ nullpo_retr(0, bl);
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ return mob_db[((struct mob_data *)bl)->class_].mexp;
+ else if(bl->type==BL_PET && (struct pet_data *)bl)
+ return mob_db[((struct pet_data *)bl)->class_].mexp;
+ else
+ return 0;
+}
+int status_get_race2(struct block_list *bl)
+{
+ nullpo_retr(0, bl);
+ if(bl->type == BL_MOB && (struct mob_data *)bl)
+ return mob_db[((struct mob_data *)bl)->class_].race2;
+ else if(bl->type==BL_PET && (struct pet_data *)bl)
+ return mob_db[((struct pet_data *)bl)->class_].race2;
+ else
+ return 0;
+}
+int status_isdead(struct block_list *bl)
+{
+ nullpo_retr(0, bl);
+ if(bl->type == BL_MOB && (struct mob_data *)bl)
+ return ((struct mob_data *)bl)->state.state == MS_DEAD;
+ else if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return pc_isdead((struct map_session_data *)bl);
+ else
+ return 0;
+}
+
+// StatusChangeŒn‚ÌŠ“¾
+struct status_change *status_get_sc_data(struct block_list *bl)
+{
+ nullpo_retr(NULL, bl);
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ return ((struct mob_data*)bl)->sc_data;
+ else if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return ((struct map_session_data*)bl)->sc_data;
+ return NULL;
+}
+short *status_get_sc_count(struct block_list *bl)
+{
+ nullpo_retr(NULL, bl);
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ return &((struct mob_data*)bl)->sc_count;
+ else if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return &((struct map_session_data*)bl)->sc_count;
+ return NULL;
+}
+short *status_get_opt1(struct block_list *bl)
+{
+ nullpo_retr(0, bl);
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ return &((struct mob_data*)bl)->opt1;
+ else if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return &((struct map_session_data*)bl)->opt1;
+ else if(bl->type==BL_NPC && (struct npc_data *)bl)
+ return &((struct npc_data*)bl)->opt1;
+ return 0;
+}
+short *status_get_opt2(struct block_list *bl)
+{
+ nullpo_retr(0, bl);
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ return &((struct mob_data*)bl)->opt2;
+ else if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return &((struct map_session_data*)bl)->opt2;
+ else if(bl->type==BL_NPC && (struct npc_data *)bl)
+ return &((struct npc_data*)bl)->opt2;
+ return 0;
+}
+short *status_get_opt3(struct block_list *bl)
+{
+ nullpo_retr(0, bl);
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ return &((struct mob_data*)bl)->opt3;
+ else if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return &((struct map_session_data*)bl)->opt3;
+ else if(bl->type==BL_NPC && (struct npc_data *)bl)
+ return &((struct npc_data*)bl)->opt3;
+ return 0;
+}
+short *status_get_option(struct block_list *bl)
+{
+ nullpo_retr(0, bl);
+ if(bl->type==BL_MOB && (struct mob_data *)bl)
+ return &((struct mob_data*)bl)->option;
+ else if(bl->type==BL_PC && (struct map_session_data *)bl)
+ return &((struct map_session_data*)bl)->status.option;
+ else if(bl->type==BL_NPC && (struct npc_data *)bl)
+ return &((struct npc_data*)bl)->option;
+ return 0;
+}
+
+int status_get_sc_def(struct block_list *bl, int type)
+{
+ int sc_def;
+ nullpo_retr(0, bl);
+
+ switch (type)
+ {
+ case SP_MDEF1: // mdef
+ sc_def = 100 - (3 + status_get_mdef(bl) + status_get_luk(bl)/3);
+ break;
+ case SP_MDEF2: // int
+ sc_def = 100 - (3 + status_get_int(bl) + status_get_luk(bl)/3);
+ break;
+ case SP_DEF1: // def
+ sc_def = 100 - (3 + status_get_def(bl) + status_get_luk(bl)/3);
+ break;
+ case SP_DEF2: // vit
+ sc_def = 100 - (3 + status_get_vit(bl) + status_get_luk(bl)/3);
+ break;
+ case SP_LUK: // luck
+ sc_def = 100 - (3 + status_get_luk(bl));
+ break;
+
+ case SC_STONE:
+ case SC_FREEZE:
+ sc_def = 100 - (3 + status_get_mdef(bl) + status_get_luk(bl)/3);
+ break;
+ case SC_STAN:
+ case SC_POISON:
+ case SC_SILENCE:
+ sc_def = 100 - (3 + status_get_vit(bl) + status_get_luk(bl)/3);
+ break;
+ case SC_SLEEP:
+ case SC_CONFUSION:
+ case SC_BLIND:
+ sc_def = 100 - (3 + status_get_int(bl) + status_get_luk(bl)/3);
+ break;
+ case SC_CURSE:
+ sc_def = 100 - (3 + status_get_luk(bl));
+ break;
+
+ default:
+ sc_def = 100;
+ break;
+ }
+
+ if(bl->type == BL_MOB) {
+ struct mob_data *md = (struct mob_data *)bl;
+ if (md && md->class_ == 1288)
+ return 0;
+ if (sc_def < 50)
+ sc_def = 50;
+ } else if(bl->type == BL_PC) {
+ struct status_change* sc_data = status_get_sc_data(bl);
+ if (sc_data && sc_data[SC_GOSPEL].timer != -1 &&
+ sc_data[SC_GOSPEL].val4 == BCT_PARTY &&
+ sc_data[SC_GOSPEL].val3 == 3)
+ sc_def -= 25;
+ }
+
+ return (sc_def < 0) ? 0 : sc_def;
+}
+
+/*==========================================
+ * ƒXƒe[ƒ^ƒXˆÙíŠJŽn
+ *------------------------------------------
+ */
+int status_change_start(struct block_list *bl,int type,int val1,int val2,int val3,int val4,int tick,int flag)
+{
+ struct map_session_data *sd = NULL;
+ struct status_change* sc_data;
+ short *sc_count, *option, *opt1, *opt2, *opt3;
+ int opt_flag = 0, calc_flag = 0,updateflag = 0, save_flag = 0, race, mode, elem, undead_flag;
+ int scdef = 0;
+ int type2 = type;
+
+ nullpo_retr(0, bl);
+ if(bl->type == BL_SKILL)
+ return 0;
+ if(bl->type == BL_MOB)
+ if (status_isdead(bl)) return 0;
+
+ nullpo_retr(0, sc_data=status_get_sc_data(bl));
+ nullpo_retr(0, sc_count=status_get_sc_count(bl));
+ nullpo_retr(0, option=status_get_option(bl));
+ nullpo_retr(0, opt1=status_get_opt1(bl));
+ nullpo_retr(0, opt2=status_get_opt2(bl));
+ nullpo_retr(0, opt3=status_get_opt3(bl));
+
+
+ race=status_get_race(bl);
+ mode=status_get_mode(bl);
+ elem=status_get_elem_type(bl);
+ undead_flag=battle_check_undead(race,elem);
+
+ if(type == SC_AETERNA && (sc_data[SC_STONE].timer != -1 || sc_data[SC_FREEZE].timer != -1) )
+ return 0;
+
+ switch(type){
+ case SC_STONE:
+ case SC_FREEZE:
+ scdef=3+status_get_mdef(bl)+status_get_luk(bl)/3;
+ break;
+ case SC_STAN:
+ case SC_SILENCE:
+ case SC_POISON:
+ case SC_DPOISON:
+ scdef=3+status_get_vit(bl)+status_get_luk(bl)/3;
+ break;
+ case SC_SLEEP:
+ case SC_BLIND:
+ scdef=3+status_get_int(bl)+status_get_luk(bl)/3;
+ break;
+ case SC_CURSE:
+ scdef=3+status_get_luk(bl);
+ break;
+
+// case SC_CONFUSION:
+ default:
+ scdef=0;
+ }
+ if(scdef>=100)
+ return 0;
+ if(bl->type==BL_PC){
+ sd=(struct map_session_data *)bl;
+ if( sd && type == SC_ADRENALINE && !(skill_get_weapontype(BS_ADRENALINE)&(1<<sd->status.weapon)))
+ return 0;
+
+ if(SC_STONE<=type && type<=SC_BLIND){ /* ƒJ?ƒh‚É‚æ‚é‘Ï« */
+ if( sd && sd->reseff[type-SC_STONE] > 0 && rand()%10000<sd->reseff[type-SC_STONE]){
+ if(battle_config.battle_log)
+ printf("PC %d skill_sc_start: card‚É‚æ‚éˆÙí‘Ï«?“®\n",sd->bl.id);
+ return 0;
+ }
+ }
+ }
+ else if(bl->type == BL_MOB) {
+ }
+ else {
+ if(battle_config.error_log)
+ printf("status_change_start: neither MOB nor PC !\n");
+ return 0;
+ }
+
+ if(type==SC_FREEZE && undead_flag && !(flag&1))
+ return 0;
+
+ if (type==SC_BLESSING && (bl->type==BL_PC || (!undead_flag && race!=6))) {
+ if (sc_data[SC_CURSE].timer!=-1)
+ status_change_end(bl,SC_CURSE,-1);
+ if (sc_data[SC_STONE].timer!=-1 && sc_data[SC_STONE].val2==0)
+ status_change_end(bl,SC_STONE,-1);
+ }
+
+ if((type == SC_ADRENALINE || type == SC_WEAPONPERFECTION || type == SC_OVERTHRUST) &&
+ sc_data[type].timer != -1 && sc_data[type].val2 && !val2)
+ return 0;
+
+ if(mode & 0x20 && (type==SC_STONE || type==SC_FREEZE ||
+ type==SC_STAN || type==SC_SLEEP || type==SC_SILENCE || type==SC_QUAGMIRE || type == SC_DECREASEAGI || type == SC_SIGNUMCRUCIS || type == SC_PROVOKE ||
+ (type == SC_BLESSING && (undead_flag || race == 6))) && !(flag&1)){
+ /* ƒ{ƒX‚É‚Í?‚©‚È‚¢(‚½‚¾‚µƒJ?ƒh‚É‚æ‚é?‰Ê‚Í“K—p‚³‚ê‚é) */
+ return 0;
+ }
+ if(type==SC_FREEZE || type==SC_STAN || type==SC_SLEEP)
+ battle_stopwalking(bl,1);
+
+ if(sc_data[type].timer != -1){ /* ‚·‚łɓ¯‚¶ˆÙí‚ɂȂÁ‚Ä‚¢‚éꇃ^ƒCƒ}‰ðœ */
+ if(sc_data[type].val1 > val1 && type != SC_COMBO && type != SC_DANCING && type != SC_DEVOTION &&
+ type != SC_SPEEDPOTION0 && type != SC_SPEEDPOTION1 && type != SC_SPEEDPOTION2 && type != SC_SPEEDPOTION3
+ && type != SC_ATKPOT && type != SC_MATKPOT) // added atk and matk potions [Valaris]
+ return 0;
+
+ if ((type >=SC_STAN && type <= SC_BLIND) || type == SC_DPOISON)
+ return 0;/* ?‚¬‘«‚µ‚ª‚Å‚«‚È‚¢?‘ÔˆÙí‚Å‚ ‚鎞‚Í?‘ÔˆÙí‚ðs‚í‚È‚¢ */
+
+ (*sc_count)--;
+ delete_timer(sc_data[type].timer, status_change_timer);
+ sc_data[type].timer = -1;
+ }
+
+ // ƒNƒAƒOƒ}ƒCƒA/Ž„‚ð–Y‚ê‚È‚¢‚Å’†‚Í–³Œø‚ȃXƒLƒ‹
+ if ((sc_data[SC_QUAGMIRE].timer!=-1 || sc_data[SC_DONTFORGETME].timer!=-1) &&
+ (type==SC_CONCENTRATE || type==SC_INCREASEAGI ||
+ type==SC_TWOHANDQUICKEN || type==SC_SPEARSQUICKEN ||
+ type==SC_ADRENALINE || type==SC_LOUD || type==SC_TRUESIGHT ||
+ type==SC_WINDWALK || type==SC_CARTBOOST || type==SC_ASSNCROS))
+ return 0;
+
+ switch(type){ /* ˆÙí‚ÌŽí—Þ‚²‚Æ‚Ì?— */
+ case SC_PROVOKE: /* ƒvƒƒ{ƒbƒN */
+ calc_flag = 1;
+ if(tick <= 0) tick = 1000; /* (ƒI?ƒgƒo?ƒT?ƒN) */
+ break;
+ case SC_ENDURE: /* ƒCƒ“ƒfƒ…ƒA */
+ if(tick <= 0) tick = 1000 * 60;
+ calc_flag = 1; // for updating mdef
+#ifdef TWILIGHT
+ val2 = 40; // [Celest]
+#else
+ val2 = 7; // [Celest]
+#endif
+ break;
+ case SC_AUTOBERSERK:
+ {
+ tick = 60*1000;
+ if (bl->type == BL_PC && sd->status.hp<sd->status.max_hp>>2 &&
+ (sc_data[SC_PROVOKE].timer==-1 || sc_data[SC_PROVOKE].val2==0))
+ status_change_start(bl,SC_PROVOKE,10,1,0,0,0,0);
+ }
+ break;
+
+ case SC_CONCENTRATE: /* W’†—ÍŒüã */
+ case SC_BLESSING: /* ƒuƒŒƒbƒVƒ“ƒO */
+ case SC_ANGELUS: /* ƒAƒ“ƒ[ƒ‹ƒX */
+ calc_flag = 1;
+ break;
+
+ case SC_INCREASEAGI: /* ‘¬“x㸠*/
+ calc_flag = 1;
+ if(sc_data[SC_DECREASEAGI].timer!=-1 )
+ status_change_end(bl,SC_DECREASEAGI,-1);
+ // the effect will still remain [celest]
+// if(sc_data[SC_WINDWALK].timer!=-1 ) /* ƒEƒCƒ“ƒhƒEƒH?ƒN */
+// status_change_end(bl,SC_WINDWALK,-1);
+ break;
+ case SC_DECREASEAGI: /* ‘¬“xŒ¸­ */
+ if (bl->type == BL_PC) // Celest
+ tick>>=1;
+ calc_flag = 1;
+ if(sc_data[SC_INCREASEAGI].timer!=-1 )
+ status_change_end(bl,SC_INCREASEAGI,-1);
+ if(sc_data[SC_ADRENALINE].timer!=-1 )
+ status_change_end(bl,SC_ADRENALINE,-1);
+ if(sc_data[SC_SPEARSQUICKEN].timer!=-1 )
+ status_change_end(bl,SC_SPEARSQUICKEN,-1);
+ if(sc_data[SC_TWOHANDQUICKEN].timer!=-1 )
+ status_change_end(bl,SC_TWOHANDQUICKEN,-1);
+ break;
+ case SC_SIGNUMCRUCIS: /* ƒVƒOƒiƒ€ƒNƒ‹ƒVƒX */
+ calc_flag = 1;
+// val2 = 14 + val1;
+ val2 = 10 + val1*2;
+ tick = 600*1000;
+ clif_emotion(bl,4);
+ break;
+ case SC_SLOWPOISON:
+ if (sc_data[SC_POISON].timer == -1 && sc_data[SC_DPOISON].timer == -1)
+ return 0;
+ break;
+ case SC_TWOHANDQUICKEN: /* 2HQ */
+ if(sc_data[SC_DECREASEAGI].timer!=-1)
+ return 0;
+ *opt3 |= 1;
+ calc_flag = 1;
+ break;
+ case SC_ADRENALINE: /* ƒAƒhƒŒƒiƒŠƒ“ƒ‰ƒbƒVƒ… */
+ if(sc_data[SC_DECREASEAGI].timer!=-1)
+ return 0;
+ if(bl->type == BL_PC)
+ if(pc_checkskill(sd,BS_HILTBINDING)>0)
+ tick += tick / 10;
+ calc_flag = 1;
+ break;
+ case SC_WEAPONPERFECTION: /* ƒEƒFƒ|ƒ“ƒp?ƒtƒFƒNƒVƒ‡ƒ“ */
+ if(bl->type == BL_PC)
+ if(pc_checkskill(sd,BS_HILTBINDING)>0)
+ tick += tick / 10;
+ break;
+ case SC_OVERTHRUST: /* ƒI?ƒo?ƒXƒ‰ƒXƒg */
+ if(bl->type == BL_PC)
+ if(pc_checkskill(sd,BS_HILTBINDING)>0)
+ tick += tick / 10;
+ *opt3 |= 2;
+ break;
+ case SC_MAXIMIZEPOWER: /* ƒ}ƒLƒVƒ}ƒCƒYƒpƒ?(SP‚ª1Œ¸‚鎞ŠÔ,val2‚É‚à) */
+ if(bl->type == BL_PC)
+ val2 = tick;
+ else
+ tick = 5000*val1;
+ break;
+ case SC_ENCPOISON: /* ƒGƒ“ƒ`ƒƒƒ“ƒgƒ|ƒCƒYƒ“ */
+ calc_flag = 1;
+ val2=(((val1 - 1) / 2) + 3)*100; /* “Å•t?Šm—¦ */
+ skill_enchant_elemental_end(bl,SC_ENCPOISON);
+ break;
+ case SC_EDP: // [Celest]
+ val2 = val1 + 2; /* –Ò“Å•t?Šm—¦(%) */
+ calc_flag = 1;
+ break;
+ case SC_POISONREACT: /* ƒ|ƒCƒYƒ“ƒŠƒAƒNƒg */
+ val2=val1/2 + val1%2; // [Celest]
+ break;
+ case SC_IMPOSITIO: /* ƒCƒ“ƒ|ƒVƒeƒBƒIƒ}ƒkƒX */
+ calc_flag = 1;
+ break;
+ case SC_ASPERSIO: /* ƒAƒXƒyƒ‹ƒVƒI */
+ skill_enchant_elemental_end(bl,SC_ASPERSIO);
+ break;
+ case SC_SUFFRAGIUM: /* ƒTƒtƒ‰ƒMƒ€ */
+ case SC_BENEDICTIO: /* ¹? */
+ case SC_MAGNIFICAT: /* ƒ}ƒOƒjƒtƒBƒJ?ƒg */
+ case SC_AETERNA: /* ƒG?ƒeƒ‹ƒi */
+ break;
+ case SC_ENERGYCOAT: /* ƒGƒiƒW?ƒR?ƒg */
+ *opt3 |= 4;
+ break;
+ case SC_MAGICROD:
+ val2 = val1*20;
+ break;
+ case SC_KYRIE: /* ƒLƒŠƒGƒGƒŒƒCƒ\ƒ“ */
+ val2 = status_get_max_hp(bl) * (val1 * 2 + 10) / 100;/* ‘Ï‹v“x */
+ val3 = (val1 / 2 + 5); /* ‰ñ? */
+// -- moonsoul (added to undo assumptio status if target has it)
+ if(sc_data[SC_ASSUMPTIO].timer!=-1 )
+ status_change_end(bl,SC_ASSUMPTIO,-1);
+ break;
+ case SC_MINDBREAKER:
+ calc_flag = 1;
+ if(tick <= 0) tick = 1000; /* (ƒI?ƒgƒo?ƒT?ƒN) */
+ case SC_GLORIA: /* ƒOƒƒŠƒA */
+ calc_flag = 1;
+ break;
+ case SC_LOUD: /* ƒ‰ƒEƒhƒ{ƒCƒX */
+ calc_flag = 1;
+ break;
+ case SC_TRICKDEAD: /* Ž€‚ñ‚¾‚Ó‚è */
+ if (bl->type == BL_PC) {
+ pc_stopattack((struct map_session_data *)sd);
+ }
+ break;
+ case SC_QUAGMIRE: /* ƒNƒ@ƒOƒ}ƒCƒA */
+ calc_flag = 1;
+ if(sc_data[SC_CONCENTRATE].timer!=-1 ) /* W’†—ÍŒüã‰ðœ */
+ status_change_end(bl,SC_CONCENTRATE,-1);
+ if(sc_data[SC_INCREASEAGI].timer!=-1 ) /* ‘¬“x㸉ðœ */
+ status_change_end(bl,SC_INCREASEAGI,-1);
+ if(sc_data[SC_TWOHANDQUICKEN].timer!=-1 )
+ status_change_end(bl,SC_TWOHANDQUICKEN,-1);
+ if(sc_data[SC_SPEARSQUICKEN].timer!=-1 )
+ status_change_end(bl,SC_SPEARSQUICKEN,-1);
+ if(sc_data[SC_ADRENALINE].timer!=-1 )
+ status_change_end(bl,SC_ADRENALINE,-1);
+ if(sc_data[SC_LOUD].timer!=-1 )
+ status_change_end(bl,SC_LOUD,-1);
+ if(sc_data[SC_TRUESIGHT].timer!=-1 ) /* ƒgƒDƒ‹?ƒTƒCƒg */
+ status_change_end(bl,SC_TRUESIGHT,-1);
+ if(sc_data[SC_WINDWALK].timer!=-1 ) /* ƒEƒCƒ“ƒhƒEƒH?ƒN */
+ status_change_end(bl,SC_WINDWALK,-1);
+ if(sc_data[SC_CARTBOOST].timer!=-1 ) /* ƒJ?ƒgƒu?ƒXƒg */
+ status_change_end(bl,SC_CARTBOOST,-1);
+ break;
+ case SC_MAGICPOWER:
+ calc_flag = 1;
+ val2 = 1;
+ break;
+ case SC_SACRIFICE:
+ val2 = 5;
+ break;
+ case SC_FLAMELAUNCHER: /* ƒtƒŒ?ƒ€ƒ‰ƒ“ƒ`ƒƒ? */
+ skill_enchant_elemental_end(bl,SC_FLAMELAUNCHER);
+ break;
+ case SC_FROSTWEAPON: /* ƒtƒƒXƒgƒEƒFƒ|ƒ“ */
+ skill_enchant_elemental_end(bl,SC_FROSTWEAPON);
+ break;
+ case SC_LIGHTNINGLOADER: /* ƒ‰ƒCƒgƒjƒ“ƒOƒ?ƒ_? */
+ skill_enchant_elemental_end(bl,SC_LIGHTNINGLOADER);
+ break;
+ case SC_SEISMICWEAPON: /* ƒTƒCƒYƒ~ƒbƒNƒEƒFƒ|ƒ“ */
+ skill_enchant_elemental_end(bl,SC_SEISMICWEAPON);
+ break;
+ case SC_DEVOTION: /* ƒfƒBƒ{?ƒVƒ‡ƒ“ */
+ calc_flag = 1;
+ break;
+ case SC_PROVIDENCE: /* ƒvƒƒ”ƒBƒfƒ“ƒX */
+ calc_flag = 1;
+ val2=val1*5;
+ break;
+ case SC_REFLECTSHIELD:
+ val2=10+val1*3;
+ break;
+ case SC_STRIPWEAPON:
+ if (val2==0) val2=90;
+ break;
+ case SC_STRIPSHIELD:
+ if (val2==0) val2=85;
+ break;
+ case SC_STRIPARMOR:
+ case SC_STRIPHELM:
+ case SC_CP_WEAPON:
+ case SC_CP_SHIELD:
+ case SC_CP_ARMOR:
+ case SC_CP_HELM:
+ break;
+
+ case SC_AUTOSPELL: /* ƒI?ƒgƒXƒyƒ‹ */
+ val4 = 5 + val1*2;
+ break;
+
+ case SC_VOLCANO:
+ calc_flag = 1;
+ val3 = val1*10;
+ //val4 = val1>=5?20: (val1==4?19: (val1==3?17: ( val1==2?14:10 ) ) );
+ break;
+ case SC_DELUGE:
+ calc_flag = 1;
+ //val3 = val1>=5?15: (val1==4?14: (val1==3?12: ( val1==2?9:5 ) ) );
+ //val4 = val1>=5?20: (val1==4?19: (val1==3?17: ( val1==2?14:10 ) ) );
+ if (sc_data[SC_FOGWALL].timer != -1 && sc_data[SC_BLIND].timer != -1)
+ status_change_end(bl,SC_BLIND,-1);
+ break;
+ case SC_VIOLENTGALE:
+ calc_flag = 1;
+ val3 = val1*3;
+ //val4 = val1>=5?20: (val1==4?19: (val1==3?17: ( val1==2?14:10 ) ) );
+ break;
+
+ case SC_SPEARSQUICKEN: /* ƒXƒsƒAƒNƒCƒbƒPƒ“ */
+ calc_flag = 1;
+ val2 = 20+val1;
+ *opt3 |= 1;
+ break;
+ case SC_COMBO:
+ break;
+ case SC_BLADESTOP_WAIT: /* ”’nŽæ‚è(‘Ò‚¿) */
+ break;
+ case SC_BLADESTOP: /* ”’nŽæ‚è */
+ if(val2==2) clif_bladestop((struct block_list *)val3,(struct block_list *)val4,1);
+ *opt3 |= 32;
+ break;
+
+ case SC_LULLABY: /* ŽqŽç‰S */
+ val2 = 11;
+ break;
+ case SC_RICHMANKIM:
+ break;
+ case SC_ETERNALCHAOS: /* ƒGƒ^?ƒiƒ‹ƒJƒIƒX */
+ calc_flag = 1;
+ break;
+ case SC_DRUMBATTLE: /* ?‘¾ŒÛ‚Ì‹¿‚« */
+ calc_flag = 1;
+ val2 = (val1+1)*25;
+ val3 = (val1+1)*2;
+ break;
+ case SC_NIBELUNGEN: /* ƒj?ƒxƒ‹ƒ“ƒO‚ÌŽw—Ö */
+ calc_flag = 1;
+ //val2 = (val1+2)*50;
+ val3 = (val1+2)*25;
+ break;
+ case SC_ROKISWEIL: /* ƒƒL‚Ì‹©‚Ñ */
+ break;
+ case SC_INTOABYSS: /* [•£‚Ì’†‚É */
+ break;
+ case SC_SIEGFRIED: /* •sŽ€g‚̃W?ƒNƒtƒŠ?ƒh */
+ calc_flag = 1;
+ val2 = 55 + val1*5;
+ val3 = val1*10;
+ break;
+ case SC_DISSONANCE: /* •s‹¦˜a‰¹ */
+ val2 = 10;
+ break;
+ case SC_WHISTLE: /* Œû“J */
+ calc_flag = 1;
+ break;
+ case SC_ASSNCROS: /* —[—z‚̃AƒTƒVƒ“ƒNƒƒX */
+ calc_flag = 1;
+ break;
+ case SC_POEMBRAGI: /* ƒuƒ‰ƒM‚ÌŽ */
+ break;
+ case SC_APPLEIDUN: /* ƒCƒhƒDƒ“‚Ì—ÑŒç */
+ calc_flag = 1;
+ break;
+ case SC_UGLYDANCE: /* Ž©•ªŸŽè‚ȃ_ƒ“ƒX */
+ val2 = 10;
+ break;
+ case SC_HUMMING: /* ƒnƒ~ƒ“ƒO */
+ calc_flag = 1;
+ break;
+ case SC_DONTFORGETME: /* Ž„‚ð–Y‚ê‚È‚¢‚Å */
+ calc_flag = 1;
+ if(sc_data[SC_INCREASEAGI].timer!=-1 ) /* ‘¬“x㸉ðœ */
+ status_change_end(bl,SC_INCREASEAGI,-1);
+ if(sc_data[SC_TWOHANDQUICKEN].timer!=-1 )
+ status_change_end(bl,SC_TWOHANDQUICKEN,-1);
+ if(sc_data[SC_SPEARSQUICKEN].timer!=-1 )
+ status_change_end(bl,SC_SPEARSQUICKEN,-1);
+ if(sc_data[SC_ADRENALINE].timer!=-1 )
+ status_change_end(bl,SC_ADRENALINE,-1);
+ if(sc_data[SC_ASSNCROS].timer!=-1 )
+ status_change_end(bl,SC_ASSNCROS,-1);
+ if(sc_data[SC_TRUESIGHT].timer!=-1 ) /* ƒgƒDƒ‹?ƒTƒCƒg */
+ status_change_end(bl,SC_TRUESIGHT,-1);
+ if(sc_data[SC_WINDWALK].timer!=-1 ) /* ƒEƒCƒ“ƒhƒEƒH?ƒN */
+ status_change_end(bl,SC_WINDWALK,-1);
+ if(sc_data[SC_CARTBOOST].timer!=-1 ) /* ƒJ?ƒgƒu?ƒXƒg */
+ status_change_end(bl,SC_CARTBOOST,-1);
+ break;
+ case SC_FORTUNE: /* K‰^‚̃LƒX */
+ calc_flag = 1;
+ break;
+ case SC_SERVICE4U: /* ƒT?ƒrƒXƒtƒH?ƒ†? */
+ calc_flag = 1;
+ break;
+ case SC_MOONLIT:
+ val2 = bl->id;
+ break;
+ case SC_DANCING: /* ƒ_ƒ“ƒX/‰‰‘t’† */
+ calc_flag = 1;
+ val3= tick / 1000;
+ tick = 1000;
+ break;
+
+ case SC_EXPLOSIONSPIRITS: // ”š—ô”g“®
+ calc_flag = 1;
+ val2 = 75 + 25*val1;
+ *opt3 |= 8;
+ break;
+ case SC_STEELBODY: // ‹à„
+ calc_flag = 1;
+ *opt3 |= 16;
+ break;
+ case SC_EXTREMITYFIST: /* ˆ¢C—…”e™€Œ */
+ break;
+ case SC_AUTOCOUNTER:
+ val3 = val4 = 0;
+ break;
+
+ case SC_SPEEDPOTION0: /* ?‘¬ƒ|?ƒVƒ‡ƒ“ */
+ case SC_SPEEDPOTION1:
+ case SC_SPEEDPOTION2:
+ case SC_SPEEDPOTION3:
+ calc_flag = 1;
+ tick = 1000 * tick;
+ val2 = 5*(2+type-SC_SPEEDPOTION0);
+ break;
+
+ /* atk & matk potions [Valaris] */
+ case SC_ATKPOT:
+ case SC_MATKPOT:
+ calc_flag = 1;
+ tick = 1000 * tick;
+ break;
+ case SC_WEDDING: //Œ‹¥—p(Œ‹¥ˆßւɂȂÁ‚Ä?‚­‚Ì‚ª?‚¢‚Æ‚©)
+ {
+ time_t timer;
+
+ calc_flag = 1;
+ tick = 10000;
+ if(!val2)
+ val2 = time(&timer);
+ }
+ break;
+ case SC_NOCHAT: //ƒ`ƒƒƒbƒg‹ÖŽ~?‘Ô
+ {
+ time_t timer;
+
+ if(!battle_config.muting_players)
+ break;
+
+ tick = 60000;
+ if(!val2)
+ val2 = time(&timer);
+ updateflag = SP_MANNER;
+ save_flag = 1; // celest
+ }
+ break;
+ case SC_SELFDESTRUCTION: //Ž©”š
+ clif_skillcasting(bl,bl->id, bl->id,0,0,331,skill_get_time(val2,val1));
+ val3 = tick / 1000;
+ tick = 1000;
+ break;
+
+ /* option1 */
+ case SC_STONE: /* Ή» */
+ if(!(flag&2)) {
+ int sc_def = status_get_mdef(bl)*200;
+ tick = tick - sc_def;
+ }
+ val3 = tick/1000;
+ if(val3 < 1) val3 = 1;
+ tick = 5000;
+ val2 = 1;
+ break;
+ case SC_SLEEP: /* ‡–° */
+ if(!(flag&2)) {
+// int sc_def = 100 - (status_get_int(bl) + status_get_luk(bl)/3);
+// tick = tick * sc_def / 100;
+// if(tick < 1000) tick = 1000;
+ tick = 30000;//‡–°‚̓Xƒe?ƒ^ƒX‘Ï«‚É?‚í‚炸30•b
+ }
+ break;
+ case SC_FREEZE: /* “€Œ‹ */
+ if(!(flag&2)) {
+ int sc_def = 100 - status_get_mdef(bl);
+ tick = tick * sc_def / 100;
+ }
+ break;
+ case SC_STAN: /* ƒXƒ^ƒ“ival2‚Ƀ~ƒŠ•bƒZƒbƒgj */
+ if(!(flag&2)) {
+ int sc_def = status_get_sc_def_vit(bl);
+ tick = tick * sc_def / 100;
+ }
+ break;
+
+ /* option2 */
+ case SC_DPOISON: /* –Ò“Å */
+ {
+ int mhp = status_get_max_hp(bl);
+ int hp = status_get_hp(bl);
+ // MHP?1/4????????
+ if (hp > mhp>>2) {
+ if(bl->type == BL_PC) {
+ int diff = mhp*10/100;
+ if (hp - diff < mhp>>2)
+ hp = hp - (mhp>>2);
+ pc_heal((struct map_session_data *)bl, -hp, 0);
+ } else if(bl->type == BL_MOB) {
+ struct mob_data *md = (struct mob_data *)bl;
+ hp -= mhp*15/100;
+ if (hp > mhp>>2)
+ md->hp = hp;
+ else
+ md->hp = mhp>>2;
+ }
+ }
+ } // fall through
+ case SC_POISON: /* “Å */
+ calc_flag = 1;
+ if(!(flag&2)) {
+ int sc_def = 100 - (status_get_vit(bl) + status_get_luk(bl)/5);
+ tick = tick * sc_def / 100;
+ }
+ val3 = tick/1000;
+ if(val3 < 1) val3 = 1;
+ tick = 1000;
+ break;
+ case SC_SILENCE: /* ’¾?iƒŒƒbƒNƒXƒfƒr?ƒij */
+ if (sc_data && sc_data[SC_GOSPEL].timer!=-1) {
+ skill_delunitgroup((struct skill_unit_group *)sc_data[SC_GOSPEL].val3);
+ status_change_end(bl,SC_GOSPEL,-1);
+ break;
+ }
+ if(!(flag&2)) {
+ int sc_def = 100 - status_get_vit(bl);
+ tick = tick * sc_def / 100;
+ }
+ break;
+ case SC_CONFUSION:
+ val2 = tick;
+ tick = 100;
+ clif_emotion(bl,1);
+ if (sd) {
+ pc_stop_walking (sd, 0);
+ }
+ break;
+ case SC_BLIND: /* ˆÃ? */
+ calc_flag = 1;
+ if(!(flag&2)) {
+ int sc_def = status_get_lv(bl)/10 + status_get_int(bl)/15;
+ tick = 30000 - sc_def;
+ }
+ break;
+ case SC_CURSE:
+ calc_flag = 1;
+ if(!(flag&2)) {
+ int sc_def = 100 - status_get_vit(bl);
+ tick = tick * sc_def / 100;
+ }
+ break;
+
+ /* option */
+ case SC_HIDING: /* ƒnƒCƒfƒBƒ“ƒO */
+ calc_flag = 1;
+ if(bl->type == BL_PC) {
+ val2 = tick / 1000; /* Ž?ŽžŠÔ */
+ tick = 1000;
+ }
+ break;
+ case SC_CHASEWALK:
+ case SC_CLOAKING: /* ƒNƒ?ƒLƒ“ƒO */
+ if(bl->type == BL_PC) {
+ calc_flag = 1; // [Celest]
+ val2 = tick;
+ val3 = type==SC_CLOAKING ? 130-val1*3 : 135-val1*5;
+ }
+ else
+ tick = 5000*val1;
+ break;
+ case SC_SIGHT: /* ƒTƒCƒg/ƒ‹ƒAƒt */
+ case SC_RUWACH:
+ val2 = tick/250;
+ tick = 10;
+ break;
+
+ /* ƒZ?ƒtƒeƒBƒEƒH?ƒ‹Aƒjƒ…?ƒ} */
+ case SC_SAFETYWALL: case SC_PNEUMA:
+ tick=((struct skill_unit *)val2)->group->limit;
+ break;
+
+ /* ƒAƒ“ƒNƒ‹ */
+ case SC_ANKLE:
+ break;
+
+ /* ƒXƒLƒ‹‚¶‚á‚È‚¢/ŽžŠÔ‚É?ŒW‚µ‚È‚¢ */
+ case SC_RIDING:
+ calc_flag = 1;
+ tick = 600*1000;
+ break;
+ case SC_FALCON:
+ case SC_WEIGHT50:
+ case SC_WEIGHT90:
+ case SC_BROKNWEAPON:
+ case SC_BROKNARMOR:
+ tick=600*1000;
+ break;
+
+ case SC_AUTOGUARD:
+ {
+ int i,t;
+ for(i=val2=0;i<val1;i++) {
+ t = 5-(i>>1);
+ val2 += (t < 0)? 1:t;
+ }
+ }
+ break;
+
+ case SC_DEFENDER:
+ calc_flag = 1;
+ val2 = 5 + val1*15;
+ break;
+
+ case SC_KEEPING:
+ case SC_BARRIER:
+ calc_flag = 1;
+
+ case SC_HALLUCINATION:
+ break;
+
+ case SC_CONCENTRATION: /* ƒRƒ“ƒZƒ“ƒgƒŒ?ƒVƒ‡ƒ“ */
+ *opt3 |= 1;
+ calc_flag = 1;
+ break;
+
+ case SC_TENSIONRELAX: /* ƒeƒ“ƒVƒ‡ƒ“ƒŠƒ‰ƒbƒNƒX */
+ if(bl->type == BL_PC) {
+ tick = 10000;
+ } else return 0;
+ break;
+
+ case SC_AURABLADE: /* ƒI?ƒ‰ƒuƒŒ?ƒh */
+ case SC_PARRYING: /* ƒpƒŠƒCƒ“ƒO */
+// case SC_ASSUMPTIO: /* */
+// case SC_HEADCRUSH: /* ƒwƒbƒhƒNƒ‰ƒbƒVƒ… */
+// case SC_JOINTBEAT: /* ƒWƒ‡ƒCƒ“ƒgƒr?ƒg */
+// case SC_MARIONETTE: /* ƒ}ƒŠƒIƒlƒbƒgƒRƒ“ƒgƒ?ƒ‹ */
+
+ //‚Ƃ肠‚¦‚¸Žè?‚«
+ break;
+
+// -- moonsoul (for new upper class related skill status effects)
+/*
+ case SC_AURABLADE:
+ val2 = val1*10;
+ break;
+ case SC_PARRYING:
+ val2=val1*3;
+ break;
+ case SC_CONCENTRATION:
+ calc_flag=1;
+ val2=val1*10;
+ val3=val1*5;
+ break;
+ case SC_TENSIONRELAX:
+// val2 = 10;
+// val3 = 15;
+ break;
+ case SC_BERSERK:
+ calc_flag=1;
+ break;
+ case SC_ASSUMPTIO:
+ if(sc_data[SC_KYRIE].timer!=-1 )
+ status_change_end(bl,SC_KYRIE,-1);
+ break;*/
+
+ case SC_WINDWALK: /* ƒEƒCƒ“ƒhƒEƒH?ƒN */
+ calc_flag = 1;
+ val2 = (val1 / 2); //Flee㸗¦
+ break;
+
+ case SC_JOINTBEAT: // Random break [DracoRPG]
+ calc_flag = 1;
+ val2 = rand()%6 + 1;
+ if (val2 == 6) status_change_start(bl,SC_BLEEDING,val1,0,0,0,skill_get_time2(type,val1),0);
+ break;
+
+ case SC_BERSERK: /* ƒo?ƒT?ƒN */
+ if(sd){
+ sd->status.hp = sd->status.max_hp * 3;
+ sd->status.sp = 0;
+ clif_updatestatus(sd,SP_HP);
+ clif_updatestatus(sd,SP_SP);
+ clif_status_change(bl,SC_INCREASEAGI,1); /* ƒAƒCƒRƒ“•\ަ */
+ sd->canregen_tick = gettick() + 300000;
+ }
+ *opt3 |= 128;
+ tick = 10000;
+ calc_flag = 1;
+ break;
+
+ case SC_ASSUMPTIO: /* ƒAƒXƒ€ƒvƒeƒBƒI */
+ if(sc_data[SC_KYRIE].timer!=-1 )
+ status_change_end(bl,SC_KYRIE,-1);
+ break;
+ *opt3 |= 2048;
+ break;
+
+ case SC_BASILICA: // [celest]
+ break;
+
+ case SC_GOSPEL:
+ if (val4 == BCT_SELF) { // self effect
+ int i;
+ if (sd) {
+ sd->canact_tick += tick;
+ sd->canmove_tick += tick;
+ }
+ val2 = tick;
+ tick = 1000;
+ for (i=0; i<=26; i++) {
+ if(sc_data[i].timer!=-1)
+ status_change_end(bl,i,-1);
+ }
+ for (i=58; i<=62; i++) {
+ if(sc_data[i].timer!=-1)
+ status_change_end(bl,i,-1);
+ }
+ for (i=132; i<=136; i++) {
+ if(sc_data[i].timer!=-1)
+ status_change_end(bl,i,-1);
+ }
+ }
+ break;
+
+ case SC_MARIONETTE: /* ƒ}ƒŠƒIƒlƒbƒgƒRƒ“ƒgƒ?ƒ‹ */
+ case SC_MARIONETTE2:
+ val2 = tick;
+ if (!val3)
+ return 0;
+ tick = 1000;
+ calc_flag = 1;
+ *opt3 |= 1024;
+ break;
+
+ case SC_MELTDOWN: /* ƒƒ‹ƒgƒ_ƒEƒ“ */
+ case SC_CARTBOOST: /* ƒJ?ƒgƒu?ƒXƒg */
+ case SC_TRUESIGHT: /* ƒgƒDƒ‹?ƒTƒCƒg */
+ case SC_SPIDERWEB: /* ƒXƒpƒCƒ_?ƒEƒFƒbƒu */
+ calc_flag = 1;
+ break;
+
+ case SC_REJECTSWORD: /* ƒŠƒWƒFƒNƒgƒ\?ƒh */
+ val2 = 3; //3‰ñU?‚𒵂˕Ԃ·
+ break;
+
+ case SC_MEMORIZE: /* ƒƒ‚ƒ‰ƒCƒY */
+ val2 = 5; //‰ñ‰r¥‚ð1/3‚É‚·‚é
+ break;
+
+ case SC_SPLASHER: /* ƒxƒiƒ€ƒXƒvƒ‰ƒbƒVƒƒ? */
+ break;
+
+ case SC_FOGWALL:
+ break;
+
+ case SC_PRESERVE:
+ break;
+
+ case SC_BLEEDING:
+ {
+ // every 1 vit deducts 1 second
+ val3 = tick - status_get_vit(bl) * 1000;
+ // minimum 50 seconds
+ if (val3 < 50000)
+ val3 = 50000;
+ val4 = 10000;
+ tick = 1000;
+ }
+ break;
+
+ case SC_SLOWDOWN:
+ case SC_SPEEDUP0:
+ calc_flag = 1;
+ break;
+
+ case SC_REGENERATION:
+ val1 = 2;
+ case SC_BATTLEORDERS:
+ tick = 60000; // 1 minute
+ calc_flag = 1;
+ break;
+
+ case SC_GUILDAURA:
+ calc_flag = 1;
+ tick = 1000;
+ break;
+
+ case SC_BABY:
+ type2 = _SC_BABY;
+ break;
+
+ default:
+ if(battle_config.error_log)
+ printf("UnknownStatusChange [%d]\n", type);
+ return 0;
+ }
+
+ if(bl->type==BL_PC &&
+ (type<SC_SENDMAX || type==SC_PRESERVE || type==SC_BATTLEORDERS || type==SC_BABY))
+ clif_status_change(bl,type2,1); /* ƒAƒCƒRƒ“•\ަ */
+
+ /* option‚Ì?X */
+ switch(type){
+ case SC_STONE:
+ case SC_FREEZE:
+ case SC_STAN:
+ case SC_SLEEP:
+ battle_stopattack(bl); /* U?’âŽ~ */
+ skill_stop_dancing(bl,0); /* ‰‰‘t/ƒ_ƒ“ƒX‚Ì’†? */
+ { /* “¯Žž‚ÉŠ|‚©‚ç‚È‚¢ƒXƒe?ƒ^ƒXˆÙí‚ð‰ðœ */
+ int i;
+ for(i = SC_STONE; i <= SC_SLEEP; i++){
+ if(sc_data[i].timer != -1){
+ (*sc_count)--;
+ delete_timer(sc_data[i].timer, status_change_timer);
+ sc_data[i].timer = -1;
+ }
+ }
+ }
+ if(type == SC_STONE)
+ *opt1 = 6;
+ else
+ *opt1 = type - SC_STONE + 1;
+ opt_flag = 1;
+ break;
+ case SC_POISON:
+ case SC_CURSE:
+ case SC_SILENCE:
+ case SC_BLIND:
+ *opt2 |= 1<<(type-SC_POISON);
+ opt_flag = 1;
+ break;
+ case SC_DPOISON: // Žb’肜ł̃GƒtƒFƒNƒg‚ðŽg—p
+ *opt2 |= 1;
+ opt_flag = 1;
+ break;
+ case SC_SIGNUMCRUCIS:
+ *opt2 |= 0x40;
+ opt_flag = 1;
+ break;
+ case SC_HIDING:
+ case SC_CLOAKING:
+ battle_stopattack(bl); /* U?’âŽ~ */
+ *option |= ((type==SC_HIDING)?2:4);
+ opt_flag =1 ;
+ break;
+ case SC_CHASEWALK:
+ battle_stopattack(bl); /* U?’âŽ~ */
+ *option |= 16388;
+ opt_flag =1 ;
+ break;
+ case SC_SIGHT:
+ *option |= 1;
+ opt_flag = 1;
+ break;
+ case SC_RUWACH:
+ *option |= 8192;
+ opt_flag = 1;
+ break;
+ case SC_WEDDING:
+ *option |= 4096;
+ opt_flag = 1;
+ }
+
+ if(opt_flag) /* option‚Ì?X */
+ clif_changeoption(bl);
+
+ (*sc_count)++; /* ƒXƒe?ƒ^ƒXˆÙí‚Ì? */
+
+ sc_data[type].val1 = val1;
+ sc_data[type].val2 = val2;
+ sc_data[type].val3 = val3;
+ sc_data[type].val4 = val4;
+ /* ƒ^ƒCƒ}?Ý’è */
+ sc_data[type].timer = add_timer(
+ gettick() + tick, status_change_timer, bl->id, type);
+
+ if(bl->type==BL_PC && calc_flag)
+ status_calc_pc(sd,0); /* ƒXƒe?ƒ^ƒXÄŒvŽZ */
+
+ if(bl->type==BL_PC && save_flag)
+ chrif_save(sd); // save the player status
+
+ if(bl->type==BL_PC && updateflag)
+ clif_updatestatus(sd,updateflag); /* ƒXƒe?ƒ^ƒX‚ðƒNƒ‰ƒCƒAƒ“ƒg‚É‘—‚é */
+
+ return 0;
+}
+/*==========================================
+ * ƒXƒe[ƒ^ƒXˆÙí‘S‰ðœ
+ *------------------------------------------
+ */
+int status_change_clear(struct block_list *bl,int type)
+{
+ struct status_change* sc_data;
+ short *sc_count, *option, *opt1, *opt2, *opt3;
+ int i;
+
+ nullpo_retr(0, bl);
+ nullpo_retr(0, sc_data = status_get_sc_data(bl));
+ nullpo_retr(0, sc_count = status_get_sc_count(bl));
+ nullpo_retr(0, option = status_get_option(bl));
+ nullpo_retr(0, opt1 = status_get_opt1(bl));
+ nullpo_retr(0, opt2 = status_get_opt2(bl));
+ nullpo_retr(0, opt3 = status_get_opt3(bl));
+
+ if (*sc_count == 0)
+ return 0;
+ for(i = 0; i < MAX_STATUSCHANGE; i++){
+ if(sc_data[i].timer != -1){ /* ˆÙ킪‚ ‚é‚È‚çƒ^ƒCƒ}?‚ð휂·‚é */
+ status_change_end(bl, i, -1);
+ }
+ }
+ *sc_count = 0;
+ *opt1 = 0;
+ *opt2 = 0;
+ *opt3 = 0;
+ *option &= OPTION_MASK;
+
+ if (night_flag == 1 && type == BL_PC && !map[bl->m].flag.indoors && // by [Yor]
+ !map[bl->m].flag.indoors && battle_config.night_darkness_level <= 0) // [celest]
+ *opt2 |= STATE_BLIND;
+
+ if(!type || type&2)
+ clif_changeoption(bl);
+
+ return 0;
+}
+
+/*==========================================
+ * ƒXƒe[ƒ^ƒXˆÙíI—¹
+ *------------------------------------------
+ */
+int status_change_end( struct block_list* bl , int type,int tid )
+{
+ struct status_change* sc_data;
+ int opt_flag=0, calc_flag = 0;
+ short *sc_count, *option, *opt1, *opt2, *opt3;
+ int type2 = type;
+
+ nullpo_retr(0, bl);
+ if(bl->type!=BL_PC && bl->type!=BL_MOB) {
+ if(battle_config.error_log)
+ printf("status_change_end: neither MOB nor PC !\n");
+ return 0;
+ }
+ nullpo_retr(0, sc_data = status_get_sc_data(bl));
+ nullpo_retr(0, sc_count = status_get_sc_count(bl));
+ nullpo_retr(0, option = status_get_option(bl));
+ nullpo_retr(0, opt1 = status_get_opt1(bl));
+ nullpo_retr(0, opt2 = status_get_opt2(bl));
+ nullpo_retr(0, opt3 = status_get_opt3(bl));
+
+ if ((*sc_count) > 0 && sc_data[type].timer != -1 && (sc_data[type].timer == tid || tid == -1)) {
+
+ if (tid == -1) // ƒ^ƒCƒ}‚©‚çŒÄ‚΂ê‚Ä‚¢‚È‚¢‚È‚çƒ^ƒCƒ}íœ‚ð‚·‚é
+ delete_timer(sc_data[type].timer,status_change_timer);
+
+ /* ŠY?‚̈Ùí‚ð³í‚É?‚· */
+ sc_data[type].timer=-1;
+ (*sc_count)--;
+
+ switch(type){ /* ˆÙí‚ÌŽí—Þ‚²‚Æ‚Ì?— */
+ case SC_PROVOKE: /* ƒvƒƒ{ƒbƒN */
+ case SC_ENDURE: // celest
+ case SC_CONCENTRATE: /* W’†—ÍŒüã */
+ case SC_BLESSING: /* ƒuƒŒƒbƒVƒ“ƒO */
+ case SC_ANGELUS: /* ƒAƒ“ƒ[ƒ‹ƒX */
+ case SC_INCREASEAGI: /* ‘¬“x㸠*/
+ case SC_DECREASEAGI: /* ‘¬“xŒ¸­ */
+ case SC_SIGNUMCRUCIS: /* ƒVƒOƒiƒ€ƒNƒ‹ƒVƒX */
+ case SC_HIDING:
+ case SC_TWOHANDQUICKEN: /* 2HQ */
+ case SC_ADRENALINE: /* ƒAƒhƒŒƒiƒŠƒ“ƒ‰ƒbƒVƒ… */
+ case SC_ENCPOISON: /* ƒGƒ“ƒ`ƒƒƒ“ƒgƒ|ƒCƒYƒ“ */
+ case SC_IMPOSITIO: /* ƒCƒ“ƒ|ƒVƒeƒBƒIƒ}ƒkƒX */
+ case SC_GLORIA: /* ƒOƒƒŠƒA */
+ case SC_LOUD: /* ƒ‰ƒEƒhƒ{ƒCƒX */
+ case SC_QUAGMIRE: /* ƒNƒ@ƒOƒ}ƒCƒA */
+ case SC_PROVIDENCE: /* ƒvƒƒ”ƒBƒfƒ“ƒX */
+ case SC_SPEARSQUICKEN: /* ƒXƒsƒAƒNƒCƒbƒPƒ“ */
+ case SC_VOLCANO:
+ case SC_DELUGE:
+ case SC_VIOLENTGALE:
+ case SC_ETERNALCHAOS: /* ƒGƒ^?ƒiƒ‹ƒJƒIƒX */
+ case SC_DRUMBATTLE: /* ?‘¾ŒÛ‚Ì‹¿‚« */
+ case SC_NIBELUNGEN: /* ƒj?ƒxƒ‹ƒ“ƒO‚ÌŽw—Ö */
+ case SC_SIEGFRIED: /* •sŽ€g‚̃W?ƒNƒtƒŠ?ƒh */
+ case SC_WHISTLE: /* Œû“J */
+ case SC_ASSNCROS: /* —[—z‚̃AƒTƒVƒ“ƒNƒƒX */
+ case SC_HUMMING: /* ƒnƒ~ƒ“ƒO */
+ case SC_DONTFORGETME: /* Ž„‚ð–Y‚ê‚È‚¢‚Å */
+ case SC_FORTUNE: /* K‰^‚̃LƒX */
+ case SC_SERVICE4U: /* ƒT?ƒrƒXƒtƒH?ƒ†? */
+ case SC_EXPLOSIONSPIRITS: // ”š—ô”g“®
+ case SC_STEELBODY: // ‹à„
+ case SC_DEFENDER:
+ case SC_SPEEDPOTION0: /* ?‘¬ƒ|?ƒVƒ‡ƒ“ */
+ case SC_SPEEDPOTION1:
+ case SC_SPEEDPOTION2:
+ case SC_SPEEDPOTION3:
+ case SC_APPLEIDUN: /* ƒCƒhƒDƒ“‚Ì—ÑŒç */
+ case SC_RIDING:
+ case SC_BLADESTOP_WAIT:
+ case SC_CONCENTRATION: /* ƒRƒ“ƒZƒ“ƒgƒŒ?ƒVƒ‡ƒ“ */
+ case SC_ASSUMPTIO: /* ƒAƒVƒƒƒ“ƒvƒeƒBƒI */
+ case SC_WINDWALK: /* ƒEƒCƒ“ƒhƒEƒH?ƒN */
+ case SC_TRUESIGHT: /* ƒgƒDƒ‹?ƒTƒCƒg */
+ case SC_SPIDERWEB: /* ƒXƒpƒCƒ_?ƒEƒFƒbƒu */
+ case SC_MAGICPOWER: /* –‚–@—Í?• */
+ case SC_CHASEWALK:
+ case SC_ATKPOT: /* attack potion [Valaris] */
+ case SC_MATKPOT: /* magic attack potion [Valaris] */
+ case SC_WEDDING: //Œ‹¥—p(Œ‹¥ˆßւɂȂÁ‚Ä?‚­‚Ì‚ª?‚¢‚Æ‚©)
+ case SC_MELTDOWN: /* ƒƒ‹ƒgƒ_ƒEƒ“ */
+ case SC_MINDBREAKER: /* ƒ}ƒCƒ“ƒhƒuƒŒ[ƒJ[ */
+ // Celest
+ case SC_EDP:
+ case SC_SLOWDOWN:
+ case SC_SPEEDUP0:
+ case SC_BATTLEORDERS:
+ case SC_REGENERATION:
+ case SC_GUILDAURA:
+ calc_flag = 1;
+ break;
+ case SC_AUTOBERSERK:
+ if (sc_data[SC_PROVOKE].timer != -1)
+ status_change_end(bl,SC_PROVOKE,-1);
+ break;
+ case SC_BERSERK: /* ƒo?ƒT?ƒN */
+ calc_flag = 1;
+ clif_status_change(bl,SC_INCREASEAGI,0); /* ƒAƒCƒRƒ“Á‹Ž */
+ break;
+ case SC_DEVOTION: /* ƒfƒBƒ{?ƒVƒ‡ƒ“ */
+ {
+ struct map_session_data *md = map_id2sd(sc_data[type].val1);
+ sc_data[type].val1=sc_data[type].val2=0;
+ skill_devotion(md,bl->id);
+ calc_flag = 1;
+ }
+ break;
+ case SC_BLADESTOP:
+ {
+ struct status_change *t_sc_data = status_get_sc_data((struct block_list *)sc_data[type].val4);
+ //•Еû‚ªØ‚ꂽ‚Ì‚Å‘ŠŽè‚Ì”’n?‘Ô‚ªØ‚ê‚ĂȂ¢‚̂Ȃç‰ðœ
+ if(t_sc_data && t_sc_data[SC_BLADESTOP].timer!=-1)
+ status_change_end((struct block_list *)sc_data[type].val4,SC_BLADESTOP,-1);
+
+ if(sc_data[type].val2==2)
+ clif_bladestop((struct block_list *)sc_data[type].val3,(struct block_list *)sc_data[type].val4,0);
+ }
+ break;
+ case SC_DANCING:
+ {
+ struct map_session_data *dsd;
+ struct status_change *d_sc_data;
+ if(sc_data[type].val4 && (dsd=map_id2sd(sc_data[type].val4))){
+ d_sc_data = dsd->sc_data;
+ //‡‘t‚Å‘ŠŽè‚ª‚¢‚éê‡‘ŠŽè‚Ìval4‚ð0‚É‚·‚é
+ if(d_sc_data && d_sc_data[type].timer!=-1)
+ d_sc_data[type].val4=0;
+ }
+ }
+ calc_flag = 1;
+ break;
+ case SC_NOCHAT: //ƒ`ƒƒƒbƒg‹ÖŽ~?‘Ô
+ {
+ struct map_session_data *sd=NULL;
+ if(bl->type == BL_PC && (sd=(struct map_session_data *)bl)){
+ if (sd->status.manner >= 0) // weeee ^^ [celest]
+ sd->status.manner = 0;
+ clif_updatestatus(sd,SP_MANNER);
+ }
+ }
+ break;
+ case SC_SPLASHER: /* ƒxƒiƒ€ƒXƒvƒ‰ƒbƒVƒƒ? */
+ {
+ struct block_list *src=map_id2bl(sc_data[type].val3);
+ if(src && tid!=-1){
+ //Ž©•ª‚Ƀ_ƒ?ƒW•Žü?3*3‚Ƀ_ƒ?ƒW
+ skill_castend_damage_id(src, bl,sc_data[type].val2,sc_data[type].val1,gettick(),0 );
+ }
+ }
+ break;
+ case SC_SELFDESTRUCTION: /* Ž©”š */
+ {
+ //Ž©•ª‚̃_ƒ?ƒW‚Í0‚É‚µ‚Ä
+ struct mob_data *md=NULL;
+ if(bl->type == BL_MOB && (md=(struct mob_data*)bl))
+ skill_castend_damage_id(bl, bl,sc_data[type].val2,sc_data[type].val1,gettick(),0 );
+ }
+ break;
+ /* option1 */
+ case SC_FREEZE:
+ sc_data[type].val3 = 0;
+ break;
+
+ /* option2 */
+ case SC_POISON: /* “Å */
+ case SC_BLIND: /* ˆÃ? */
+ case SC_CURSE:
+ calc_flag = 1;
+ break;
+
+ // celest
+ case SC_CONFUSION:
+ {
+ struct map_session_data *sd=NULL;
+ if(bl->type == BL_PC && (sd=(struct map_session_data *)bl)){
+ sd->next_walktime = -1;
+ }
+ }
+ break;
+
+ case SC_MARIONETTE: /* ƒ}ƒŠƒIƒlƒbƒgƒRƒ“ƒgƒ?ƒ‹ */
+ case SC_MARIONETTE2: /// Marionette target
+ {
+ // check for partner and end their marionette status as well
+ int type2 = (type == SC_MARIONETTE) ? SC_MARIONETTE2 : SC_MARIONETTE;
+ struct block_list *pbl = map_id2bl(sc_data[type].val3);
+ if (pbl) {
+ struct status_change* sc_data;
+ if (*status_get_sc_count(pbl) > 0 &&
+ (sc_data = status_get_sc_data(pbl)) &&
+ sc_data[type2].timer != -1)
+ status_change_end(pbl, type2, -1);
+ }
+ calc_flag = 1;
+ }
+ break;
+
+ case SC_BABY:
+ type2 = _SC_BABY;
+ break;
+ }
+
+ if(bl->type==BL_PC &&
+ (type<SC_SENDMAX || type==SC_PRESERVE || type==SC_BATTLEORDERS || type==SC_BABY))
+ clif_status_change(bl,type2,0); /* ƒAƒCƒRƒ“Á‹Ž */
+
+ switch(type){ /* ³í‚É?‚邯‚«‚Ȃɂ©?—‚ª•K—v */
+ case SC_STONE:
+ case SC_FREEZE:
+ case SC_STAN:
+ case SC_SLEEP:
+ *opt1 = 0;
+ opt_flag = 1;
+ break;
+
+ case SC_POISON:
+ if (sc_data[SC_DPOISON].timer != -1) //
+ break; // DPOISON—p‚̃IƒvƒVƒ‡ƒ“
+ *opt2 &= ~1; // ‚ª?—p‚É—pˆÓ‚³‚ꂽꇂɂÍ
+ opt_flag = 1; // ‚±‚±‚Í휂·‚é
+ break; //
+ case SC_CURSE:
+ case SC_SILENCE:
+ case SC_BLIND:
+ *opt2 &= ~(1<<(type-SC_POISON));
+ opt_flag = 1;
+ break;
+ case SC_DPOISON:
+ if (sc_data[SC_POISON].timer != -1) // DPOISON—p‚̃IƒvƒVƒ‡ƒ“‚ª
+ break; // —pˆÓ‚³‚ꂽ‚çíœ
+ *opt2 &= ~1; // “Å?‘Ô‰ðœ
+ opt_flag = 1;
+ break;
+ case SC_SIGNUMCRUCIS:
+ *opt2 &= ~0x40;
+ opt_flag = 1;
+ break;
+
+ case SC_HIDING:
+ case SC_CLOAKING:
+ *option &= ~((type == SC_HIDING) ? 2 : 4);
+ calc_flag = 1; // orn
+ opt_flag = 1 ;
+ break;
+
+ case SC_CHASEWALK:
+ *option &= ~16388;
+ opt_flag = 1 ;
+ break;
+
+ case SC_SIGHT:
+ *option &= ~1;
+ opt_flag = 1;
+ break;
+ case SC_WEDDING: //Œ‹¥—p(Œ‹¥ˆßւɂȂÁ‚Ä?‚­‚Ì‚ª?‚¢‚Æ‚©)
+ *option &= ~4096;
+ opt_flag = 1;
+ break;
+ case SC_RUWACH:
+ *option &= ~8192;
+ opt_flag = 1;
+ break;
+
+ //opt3
+ case SC_TWOHANDQUICKEN: /* 2HQ */
+ case SC_SPEARSQUICKEN: /* ƒXƒsƒAƒNƒCƒbƒPƒ“ */
+ case SC_CONCENTRATION: /* ƒRƒ“ƒZƒ“ƒgƒŒ?ƒVƒ‡ƒ“ */
+ *opt3 &= ~1;
+ break;
+ case SC_OVERTHRUST: /* ƒI?ƒo?ƒXƒ‰ƒXƒg */
+ *opt3 &= ~2;
+ break;
+ case SC_ENERGYCOAT: /* ƒGƒiƒW?ƒR?ƒg */
+ *opt3 &= ~4;
+ break;
+ case SC_EXPLOSIONSPIRITS: // ”š—ô”g“®
+ *opt3 &= ~8;
+ break;
+ case SC_STEELBODY: // ‹à„
+ *opt3 &= ~16;
+ break;
+ case SC_BLADESTOP: /* ”’nŽæ‚è */
+ *opt3 &= ~32;
+ break;
+ case SC_BERSERK: /* ƒo?ƒT?ƒN */
+ *opt3 &= ~128;
+ break;
+ case SC_MARIONETTE: /* ƒ}ƒŠƒIƒlƒbƒgƒRƒ“ƒgƒ?ƒ‹ */
+ case SC_MARIONETTE2:
+ *opt3 &= ~1024;
+ break;
+ case SC_ASSUMPTIO: /* ƒAƒXƒ€ƒvƒeƒBƒI */
+ *opt3 &= ~2048;
+ break;
+ }
+
+ if (night_flag == 1 && (*opt2 & STATE_BLIND) == 0 && bl->type == BL_PC && // by [Yor]
+ !map[bl->m].flag.indoors && battle_config.night_darkness_level <= 0) { // [celest]
+ *opt2 |= STATE_BLIND;
+ opt_flag = 1;
+ }
+
+ if(opt_flag) /* option‚Ì?X‚ð?‚¦‚é */
+ clif_changeoption(bl);
+
+ if (bl->type == BL_PC && calc_flag)
+ status_calc_pc((struct map_session_data *)bl,0); /* ƒXƒe?ƒ^ƒXÄŒvŽZ */
+ }
+
+ return 0;
+}
+
+
+/*==========================================
+ * ƒXƒe[ƒ^ƒXˆÙíI—¹ƒ^ƒCƒ}[
+ *------------------------------------------
+ */
+int status_change_timer(int tid, unsigned int tick, int id, int data)
+{
+ int type = data;
+ struct block_list *bl;
+ struct map_session_data *sd=NULL;
+ struct status_change *sc_data;
+ //short *sc_count; //Žg‚Á‚ĂȂ¢H
+
+// security system to prevent forgetting timer removal
+ int temp_timerid;
+
+ bl=map_id2bl(id);
+#ifndef _WIN32
+ nullpo_retr_f(0, bl, "id=%d data=%d",id,data);
+#endif
+ nullpo_retr(0, sc_data=status_get_sc_data(bl));
+
+ if(bl->type==BL_PC)
+ nullpo_retr(0, sd=(struct map_session_data *)bl);
+
+ //sc_count=status_get_sc_count(bl); //Žg‚Á‚ĂȂ¢H
+
+ if(sc_data[type].timer != tid) {
+ if(battle_config.error_log)
+ printf("status_change_timer %d != %d\n",tid,sc_data[type].timer);
+ return 0;
+ }
+
+ // security system to prevent forgetting timer removal
+ // you shouldn't be that careless inside the switch here
+ temp_timerid = sc_data[type].timer;
+ sc_data[type].timer = -1;
+
+ switch(type){ /* “ÁŽê‚È?—‚ɂȂéê‡ */
+ case SC_MAXIMIZEPOWER: /* ƒ}ƒLƒVƒ}ƒCƒYƒpƒ? */
+ case SC_CLOAKING:
+ if(sd){
+ if( sd->status.sp > 0 ){ /* SPØ‚ê‚é‚܂Ŏ? */
+ sd->status.sp--;
+ clif_updatestatus(sd,SP_SP);
+ sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
+ sc_data[type].val2+tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ }
+ break;
+
+ case SC_CHASEWALK:
+ if(sd){
+ int sp = 10+sc_data[SC_CHASEWALK].val1*2;
+ if (map[sd->bl.m].flag.gvg) sp *= 5;
+ if( sd->status.sp > sp){
+ sd->status.sp -= sp; // update sp cost [Celest]
+ clif_updatestatus(sd,SP_SP);
+ sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
+ sc_data[type].val2+tick, status_change_timer, bl->id, data);
+ sc_data[SC_CHASEWALK].val4++;
+ if (sc_data[SC_CHASEWALK].val4 > 3)
+ sc_data[SC_CHASEWALK].val4 = 0;
+ status_calc_pc (sd, 0);
+ return 0;
+ }
+ }
+ break;
+
+ case SC_HIDING: /* ƒnƒCƒfƒBƒ“ƒO */
+ if(sd){ /* SP‚ª‚ ‚Á‚ÄAŽžŠÔ§ŒÀ‚ÌŠÔ‚ÍŽ? */
+ if( sd->status.sp > 0 && (--sc_data[type].val2)>0 ){
+ if(sc_data[type].val2 % (sc_data[type].val1+3) ==0 ){
+ sd->status.sp--;
+ clif_updatestatus(sd,SP_SP);
+ }
+ sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
+ 1000+tick, status_change_timer,
+ bl->id, data);
+ return 0;
+ }
+ }
+ break;
+
+ case SC_SIGHT: /* ƒTƒCƒg */
+ case SC_RUWACH: /* ƒ‹ƒAƒt */
+ {
+ int range = 5;
+ if ( type == SC_SIGHT ) range = 7;
+ map_foreachinarea( status_change_timer_sub,
+ bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,0,
+ bl,type,tick);
+
+ if( (--sc_data[type].val2)>0 ){
+ sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
+ 250+tick, status_change_timer,
+ bl->id, data);
+ return 0;
+ }
+ }
+ break;
+
+ case SC_SIGNUMCRUCIS: /* ƒVƒOƒiƒ€ƒNƒ‹ƒVƒX */
+ {
+ int race = status_get_race(bl);
+ if(race == 6 || battle_check_undead(race,status_get_elem_type(bl))) {
+ sc_data[type].timer=add_timer(1000*600+tick,status_change_timer, bl->id, data );
+ return 0;
+ }
+ }
+ break;
+
+ case SC_PROVOKE: /* ƒvƒƒ{ƒbƒN/ƒI?ƒgƒo?ƒT?ƒN */
+ if(sc_data[type].val2!=0){ /* ƒI?ƒgƒo?ƒT?ƒNi‚P•b‚²‚Æ‚ÉHPƒ`ƒFƒbƒNj */
+ if(sd && sd->status.hp>sd->status.max_hp>>2) /* ’âŽ~ */
+ break;
+ sc_data[type].timer=add_timer( 1000+tick,status_change_timer, bl->id, data );
+ return 0;
+ }
+ break;
+
+ case SC_ENDURE: /* ƒCƒ“ƒfƒ…ƒA */
+ case SC_AUTOBERSERK: // Celest
+ if(sd && sd->special_state.infinite_endure) {
+#ifdef TWILIGHT
+ sc_data[type].timer=add_timer( 1000*600+tick,status_change_timer, bl->id, data );
+#else
+ sc_data[type].timer=add_timer( 1000*60+tick,status_change_timer, bl->id, data );
+#endif
+ //sc_data[type].val2=1;
+ return 0;
+ }
+ break;
+
+ case SC_DISSONANCE: /* •s‹¦˜a‰¹ */
+ if( (--sc_data[type].val2)>0){
+ struct skill_unit *unit=
+ (struct skill_unit *)sc_data[type].val4;
+ struct block_list *src;
+ /*if(!unit || !unit->group)
+ break;
+ src=map_id2bl(unit->group->src_id);
+ if(!src)
+ break;*/
+ nullpo_retb(unit);
+ nullpo_retb(unit->group);
+ nullpo_retb(src=map_id2bl(unit->group->src_id));
+ skill_attack(BF_MISC,src,&unit->bl,bl,unit->group->skill_id,sc_data[type].val1,tick,0);
+ if( (bl->type==BL_MOB) && (MS_DEAD==((struct mob_data *)bl)->state.state) )
+ break;
+ sc_data[type].timer=add_timer(skill_get_time2(unit->group->skill_id,unit->group->skill_lv)+tick,
+ status_change_timer, bl->id, data );
+ return 0;
+ }
+ break;
+
+ case SC_LULLABY: /* ŽqŽç‰S */
+ if( (--sc_data[type].val2)>0){
+ struct skill_unit *unit=
+ (struct skill_unit *)sc_data[type].val4;
+ nullpo_retb(unit);
+ nullpo_retb(unit->group);
+ if(unit->group->src_id == bl->id)
+ break;
+ skill_additional_effect(bl,bl,unit->group->skill_id,sc_data[type].val1,BF_LONG|BF_SKILL|BF_MISC,tick);
+ if (unit->group != 0)
+ {
+ sc_data[type].timer=add_timer(skill_get_time(unit->group->skill_id,unit->group->skill_lv)/10+tick,
+ status_change_timer, bl->id, data );
+ return 0;
+ }// dont forget the brackets
+ }
+ break;
+
+ case SC_STONE:
+ if(sc_data[type].val2 != 0) {
+ short *opt1 = status_get_opt1(bl);
+ sc_data[type].val2 = 0;
+ sc_data[type].val4 = 0;
+ battle_stopwalking(bl,1);
+ if(opt1) {
+ *opt1 = 1;
+ clif_changeoption(bl);
+ }
+ sc_data[type].timer=add_timer(1000+tick,status_change_timer, bl->id, data );
+ return 0;
+ }
+ else if( (--sc_data[type].val3) > 0) {
+ int hp = status_get_max_hp(bl);
+ if((++sc_data[type].val4)%5 == 0 && status_get_hp(bl) > hp>>2) {
+ hp = hp/100;
+ if(hp < 1) hp = 1;
+ if(sd)
+ pc_heal(sd,-hp,0);
+ else if(bl->type == BL_MOB){
+ struct mob_data *md;
+ if((md=((struct mob_data *)bl)) == NULL)
+ break;
+ md->hp -= hp;
+ }
+ }
+ sc_data[type].timer=add_timer(1000+tick,status_change_timer, bl->id, data );
+ return 0;
+ }
+ break;
+
+ case SC_POISON:
+ case SC_DPOISON:
+ if (sc_data[SC_SLOWPOISON].timer == -1 && (--sc_data[type].val3) > 0) {
+ int hp = status_get_max_hp(bl);
+ if (type == SC_POISON && status_get_hp(bl) < hp>>2)
+ break;
+ if(sd) {
+ hp = (type == SC_DPOISON) ? 3 + hp/50 : 3 + hp*3/200;
+ pc_heal(sd, -hp, 0);
+ } else if (bl->type == BL_MOB) {
+ struct mob_data *md;
+ nullpo_retr(0, md=(struct mob_data *)bl);
+ hp = (type == SC_DPOISON) ? 3 + hp/100 : 3 + hp/200;
+ md->hp -= hp;
+ }
+ }
+ if (sc_data[type].val3 > 0)
+ {
+ sc_data[type].timer=add_timer(1000+tick,status_change_timer, bl->id, data );
+ // hmm setting up a timer and breaking then to call status_change_end just right away?
+ // I think you're missing brackets and a:
+ return 0;
+ }
+ break;
+
+ case SC_TENSIONRELAX: /* ƒeƒ“ƒVƒ‡ƒ“ƒŠƒ‰ƒbƒNƒX */
+ if(sd){ /* SP‚ª‚ ‚Á‚ÄAHP‚ª?ƒ^ƒ“‚łȂ¯‚ê‚Î?? */
+ if( sd->status.sp > 12 && sd->status.max_hp > sd->status.hp ){
+/* if(sc_data[type].val2 % (sc_data[type].val1+3) ==0 ){
+ sd->status.sp -= 12;
+ clif_updatestatus(sd,SP_SP);
+ } */
+ sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
+ 10000+tick, status_change_timer,
+ bl->id, data);
+ return 0;
+ }
+ if(sd->status.max_hp <= sd->status.hp)
+ {
+ status_change_end(&sd->bl,SC_TENSIONRELAX,-1);
+ // calling status_change_end then break and call it again might not be that what is necessary
+ // or am I wrong?
+ // so I just add brackets and a:
+ return 0;
+ }
+ }
+ break;
+ case SC_BLEEDING: // [celest]
+ // i hope i haven't interpreted it wrong.. which i might ^^;
+ // Source:
+ // - 10õ©ª´ªÈªËHPª¬Êõá´
+ // - õóúìªÎªÞªÞ«µ?«Ðì¹ÔѪä«ê«í«°ª·ªÆªâ?ÍýªÏἪ¨ªÊª¤
+ if((sc_data[type].val3 -= 1000) > 0) {
+ if((sc_data[type].val4 -= 1000) > 0) {
+ int hp = rand()%300+400;
+ if(sd) {
+ pc_heal(sd,-hp,0);
+ sd->canmove_tick = tick+1000;
+ }
+ else if(bl->type == BL_MOB) {
+ struct mob_data *md;
+ nullpo_retr(0, md=(struct mob_data *)bl);
+ md->hp -= hp;
+ }
+ }
+ if (sd) {
+ sd->canact_tick = tick+1000;
+ }
+
+ sc_data[type].timer=add_timer(1000+tick,status_change_timer, bl->id, data );
+ // hmm setting up a timer and breaking then to call status_change_end just right away?
+ // I think you're missing a:
+ return 0;
+ }
+ break;
+
+ /* ŽžŠÔ؂ꖳ‚µHH */
+ case SC_AETERNA:
+ case SC_TRICKDEAD:
+ case SC_RIDING:
+ case SC_FALCON:
+ case SC_WEIGHT50:
+ case SC_WEIGHT90:
+ case SC_MAGICPOWER: /* –‚–@—Í?• */
+ case SC_REJECTSWORD: /* ƒŠƒWƒFƒNƒgƒ\?ƒh */
+ case SC_MEMORIZE: /* ƒƒ‚ƒ‰ƒCƒY */
+ case SC_BROKNWEAPON:
+ case SC_BROKNARMOR:
+ case SC_SACRIFICE:
+ sc_data[type].timer=add_timer( 1000*600+tick,status_change_timer, bl->id, data );
+ return 0;
+
+ case SC_DANCING: //ƒ_ƒ“ƒXƒXƒLƒ‹‚ÌŽžŠÔSPÁ”ï
+ {
+ int s=0;
+ if(sd){
+ if(sd->status.sp > 0 && (--sc_data[type].val3)>0){
+ switch(sc_data[type].val1){
+ case BD_RICHMANKIM: /* ƒjƒˆƒ‹ƒh‚̉ƒ 3•b‚ÉSP1 */
+ case BD_DRUMBATTLEFIELD: /* ?‘¾ŒÛ‚Ì‹¿‚« 3•b‚ÉSP1 */
+ case BD_RINGNIBELUNGEN: /* ƒj?ƒxƒ‹ƒ“ƒO‚ÌŽw—Ö 3•b‚ÉSP1 */
+ case BD_SIEGFRIED: /* •sŽ€g‚̃W?ƒNƒtƒŠ?ƒh 3•b‚ÉSP1 */
+ case BA_DISSONANCE: /* •s‹¦˜a‰¹ 3•b‚ÅSP1 */
+ case BA_ASSASSINCROSS: /* —[—z‚̃AƒTƒVƒ“ƒNƒƒX 3•b‚ÅSP1 */
+ case DC_UGLYDANCE: /* Ž©•ªŸŽè‚ȃ_ƒ“ƒX 3•b‚ÅSP1 */
+ s=3;
+ break;
+ case BD_LULLABY: /* ŽqŽç‰Ì 4•b‚ÉSP1 */
+ case BD_ETERNALCHAOS: /* ‰i‰“‚̬“× 4•b‚ÉSP1 */
+ case BD_ROKISWEIL: /* ƒƒL‚Ì‹©‚Ñ 4•b‚ÉSP1 */
+ case DC_FORTUNEKISS: /* K‰^‚̃LƒX 4•b‚ÅSP1 */
+ s=4;
+ break;
+ case BD_INTOABYSS: /* [•£‚Ì’†‚É 5•b‚ÉSP1 */
+ case BA_WHISTLE: /* Œû“J 5•b‚ÅSP1 */
+ case DC_HUMMING: /* ƒnƒ~ƒ“ƒO 5•b‚ÅSP1 */
+ case BA_POEMBRAGI: /* ƒuƒ‰ƒM‚ÌŽ 5•b‚ÅSP1 */
+ case DC_SERVICEFORYOU: /* ƒT?ƒrƒXƒtƒH?ƒ†? 5•b‚ÅSP1 */
+ s=5;
+ break;
+ case BA_APPLEIDUN: /* ƒCƒhƒDƒ“‚Ì—ÑŒç 6•b‚ÅSP1 */
+ s=6;
+ break;
+ case DC_DONTFORGETME: /* Ž„‚ð–Y‚ê‚È‚¢‚Åc 10•b‚ÅSP1 */
+ case CG_MOONLIT: /* ŒŽ–¾‚è‚Ìò‚É—Ž‚¿‚é‰Ô‚Ñ‚ç 10•b‚ÅSP1H */
+ s=10;
+ break;
+ }
+ if(s && ((sc_data[type].val3 % s) == 0)){
+ sd->status.sp--;
+ clif_updatestatus(sd,SP_SP);
+ }
+ sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
+ 1000+tick, status_change_timer,
+ bl->id, data);
+ return 0;
+ }
+ }
+ }
+ break;
+ case SC_BERSERK: /* ƒo?ƒT?ƒN */
+ if(sd){ /* HP‚ª100ˆÈã‚È‚ç?? */
+ if( (sd->status.hp - sd->status.max_hp*5/100) > 100 ){ // 5% every 10 seconds [DracoRPG]
+ sd->status.hp -= sd->status.max_hp*5/100; // changed to max hp [celest]
+ clif_updatestatus(sd,SP_HP);
+ sc_data[type].timer = add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
+ 10000+tick, status_change_timer,
+ bl->id, data);
+ return 0;
+ }
+ }
+ break;
+ case SC_WEDDING: //Œ‹¥—p(Œ‹¥ˆßւɂȂÁ‚Ä?‚­‚Ì‚ª?‚¢‚Æ‚©)
+ if(sd){
+ time_t timer;
+ if(time(&timer) < ((sc_data[type].val2) + 3600)){ //1ŽžŠÔ‚½‚Á‚Ä‚¢‚È‚¢‚Ì‚Å??
+ sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
+ 10000+tick, status_change_timer,
+ bl->id, data);
+ return 0;
+ }
+ }
+ break;
+ case SC_NOCHAT: //ƒ`ƒƒƒbƒg‹ÖŽ~?‘Ô
+ if(sd && battle_config.muting_players){
+ time_t timer;
+ if((++sd->status.manner) && time(&timer) < ((sc_data[type].val2) + 60*(0-sd->status.manner))){ //ŠJŽn‚©‚çstatus.manner•ª?‚Á‚ĂȂ¢‚Ì‚Å??
+ clif_updatestatus(sd,SP_MANNER);
+ sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è(60•b) */
+ 60000+tick, status_change_timer,
+ bl->id, data);
+ return 0;
+ }
+ }
+ break;
+ case SC_SELFDESTRUCTION: /* Ž©”š */
+ if(--sc_data[type].val3>0){
+ struct mob_data *md;
+ if(bl->type==BL_MOB && (md=(struct mob_data *)bl) && md->speed > 250){
+ md->speed -= 250;
+ md->next_walktime=tick;
+ }
+ sc_data[type].timer=add_timer( /* ƒ^ƒCƒ}?ÄÝ’è */
+ 1000+tick, status_change_timer,
+ bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_SPLASHER:
+ if (sc_data[type].val4 % 1000 == 0) {
+ char timer[2];
+ sprintf (timer, "%d", sc_data[type].val4/1000);
+ clif_message(bl, timer);
+ }
+ if((sc_data[type].val4 -= 500) > 0) {
+ sc_data[type].timer = add_timer(
+ 500 + tick, status_change_timer,
+ bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_MARIONETTE: /* ƒ}ƒŠƒIƒlƒbƒgƒRƒ“ƒgƒ?ƒ‹ */
+ case SC_MARIONETTE2:
+ {
+ struct block_list *pbl = map_id2bl(sc_data[type].val3);
+ if (pbl && battle_check_range(bl, pbl, 7) &&
+ (sc_data[type].val2 -= 1000)>0) {
+ sc_data[type].timer = add_timer(
+ 1000 + tick, status_change_timer,
+ bl->id, data);
+ return 0;
+ }
+ }
+ break;
+
+ // Celest
+ case SC_CONFUSION:
+ {
+ int i = 3000;
+ //struct mob_data *md;
+ if (sd) {
+ pc_randomwalk (sd, gettick());
+ sd->next_walktime = tick + (i=1000 + rand()%1000);
+ } /*else if (bl->type==BL_MOB && (md=(struct mob_data *)bl) && md->mode&1 && mob_can_move(md)) {
+ md->state.state=MS_WALK;
+ if( DIFF_TICK(md->next_walktime,tick) > + 7000 &&
+ (md->walkpath.path_len==0 || md->walkpath.path_pos>=md->walkpath.path_len) )
+ md->next_walktime = tick + 3000*rand()%2000;
+ mob_randomwalk(md,tick);
+ }*/
+ if ((sc_data[type].val2 -= 1000) > 0) {
+ sc_data[type].timer = add_timer(
+ i + tick, status_change_timer,
+ bl->id, data);
+ return 0;
+ }
+ }
+ break;
+
+ case SC_GOSPEL:
+ {
+ int calc_flag = 0;
+ if (sc_data[type].val3 > 0) {
+ sc_data[type].val3 = 0;
+ calc_flag = 1;
+ }
+ if(sd && sc_data[type].val4 == BCT_SELF){
+ int hp, sp;
+ hp = (sc_data[type].val1 > 5) ? 45 : 30;
+ sp = (sc_data[type].val1 > 5) ? 35 : 20;
+ if(sd->status.hp - hp > 0 &&
+ sd->status.sp - sp > 0){
+ sd->status.hp -= hp;
+ sd->status.sp -= sp;
+ clif_updatestatus(sd,SP_HP);
+ clif_updatestatus(sd,SP_SP);
+ if ((sc_data[type].val2 -= 10000) > 0) {
+ sc_data[type].timer = add_timer(
+ 10000+tick, status_change_timer,
+ bl->id, data);
+ return 0;
+ }
+ }
+ } else if (sd && sc_data[type].val4 == BCT_PARTY) {
+ int i;
+ switch ((i = rand() % 12)) {
+ case 1: // heal between 100-1000
+ {
+ struct block_list tbl;
+ int heal = rand() % 900 + 100;
+ tbl.id = 0;
+ tbl.m = bl->m;
+ tbl.x = bl->x;
+ tbl.y = bl->y;
+ clif_skill_nodamage(&tbl,bl,AL_HEAL,heal,1);
+ battle_heal(NULL,bl,heal,0,0);
+ }
+ break;
+ case 2: // end negative status
+ {
+ int j;
+ for (j=0; j<4; j++)
+ if(sc_data[i + SC_POISON].timer!=-1) {
+ status_change_end(bl,j,-1);
+ break;
+ }
+ }
+ break;
+ case 3: // +25% resistance to negative status
+ case 4: // +25% max hp
+ case 5: // +25% max sp
+ case 6: // +2 to all stats
+ case 11: // +25% armor and vit def
+ case 12: // +8% atk
+ case 13: // +5% flee
+ case 14: // +5% hit
+ sc_data[type].val3 = i;
+ if (i == 6 ||
+ (i >= 11 && i <= 14))
+ calc_flag = 1;
+ break;
+ case 7: // level 5 bless
+ {
+ struct block_list tbl;
+ tbl.id = 0;
+ tbl.m = bl->m;
+ tbl.x = bl->x;
+ tbl.y = bl->y;
+ clif_skill_nodamage(&tbl,bl,AL_BLESSING,5,1);
+ status_change_start(bl,SkillStatusChangeTable[AL_BLESSING],5,0,0,0,10000,0 );
+ }
+ break;
+ case 8: // level 5 increase agility
+ {
+ struct block_list tbl;
+ tbl.id = 0;
+ tbl.m = bl->m;
+ tbl.x = bl->x;
+ tbl.y = bl->y;
+ clif_skill_nodamage(&tbl,bl,AL_INCAGI,5,1);
+ status_change_start(bl,SkillStatusChangeTable[AL_INCAGI],5,0,0,0,10000,0 );
+ }
+ break;
+ case 9: // holy element to weapon
+ {
+ struct block_list tbl;
+ tbl.id = 0;
+ tbl.m = bl->m;
+ tbl.x = bl->x;
+ tbl.y = bl->y;
+ clif_skill_nodamage(&tbl,bl,PR_ASPERSIO,1,1);
+ status_change_start(bl,SkillStatusChangeTable[PR_ASPERSIO],1,0,0,0,10000,0 );
+ }
+ break;
+ case 10: // holy element to armour
+ {
+ struct block_list tbl;
+ tbl.id = 0;
+ tbl.m = bl->m;
+ tbl.x = bl->x;
+ tbl.y = bl->y;
+ clif_skill_nodamage(&tbl,bl,PR_BENEDICTIO,1,1);
+ status_change_start(bl,SkillStatusChangeTable[PR_BENEDICTIO],1,0,0,0,10000,0 );
+ }
+ break;
+ default:
+ break;
+ }
+ } else if (sc_data[type].val4 == BCT_ENEMY) {
+ int i;
+ switch ((i = rand() % 8)) {
+ case 1: // damage between 300-800
+ case 2: // damage between 150-550 (ignore def)
+ battle_damage(NULL, bl, rand() % 500,0); // temporary damage
+ break;
+ case 3: // random status effect
+ {
+ int effect[3] = {
+ SC_CURSE,
+ SC_BLIND,
+ SC_POISON };
+ status_change_start(bl,effect[rand()%3],1,0,0,0,10000,0 );
+ }
+ break;
+ case 4: // level 10 provoke
+ {
+ struct block_list tbl;
+ tbl.id = 0;
+ tbl.m = bl->m;
+ tbl.x = bl->x;
+ tbl.y = bl->y;
+ clif_skill_nodamage(&tbl,bl,SM_PROVOKE,1,1);
+ status_change_start(bl,SkillStatusChangeTable[SM_PROVOKE],10,0,0,0,10000,0 );
+ }
+ break;
+ case 5: // 0 def
+ case 6: // 0 atk
+ case 7: // 0 flee
+ case 8: // -75% move speed and aspd
+ sc_data[type].val3 = i;
+ calc_flag = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ if (sd && calc_flag)
+ status_calc_pc (sd, 0);
+ }
+ break;
+
+ case SC_GUILDAURA:
+ {
+ struct block_list *tbl = map_id2bl(sc_data[type].val2);
+
+ if (tbl && battle_check_range(bl, tbl, 2)){
+ sc_data[type].timer = add_timer(
+ 1000 + tick, status_change_timer,
+ bl->id, data);
+ return 0;
+ }// ugh, don't forget the brackets
+ }
+ break;
+ }
+
+ // default for all non-handled control paths
+ // security system to prevent forgetting timer removal
+
+ // if we reach this point we need the timer for the next call,
+ // so restore it to have status_change_end handle a valid timer
+ sc_data[type].timer = temp_timerid;
+
+ return status_change_end( bl,type,tid );
+}
+
+/*==========================================
+ * ƒXƒe[ƒ^ƒXˆÙíƒ^ƒCƒ}[”͈͈—
+ *------------------------------------------
+ */
+int status_change_timer_sub(struct block_list *bl, va_list ap )
+{
+ struct block_list *src;
+ int type;
+ unsigned int tick;
+
+ nullpo_retr(0, bl);
+ nullpo_retr(0, ap);
+ nullpo_retr(0, src=va_arg(ap,struct block_list*));
+ type=va_arg(ap,int);
+ tick=va_arg(ap,unsigned int);
+
+ if(bl->type!=BL_PC && bl->type!=BL_MOB)
+ return 0;
+
+ switch( type ){
+ case SC_SIGHT: /* ƒTƒCƒg */
+ case SC_CONCENTRATE:
+ if( (*status_get_option(bl))&6 ){
+ status_change_end( bl, SC_HIDING, -1);
+ status_change_end( bl, SC_CLOAKING, -1);
+ }
+ break;
+ case SC_RUWACH: /* ƒ‹ƒAƒt */
+ if( (*status_get_option(bl))&6 ){
+ struct status_change *sc_data = status_get_sc_data(bl); // check whether the target is hiding/cloaking [celest]
+ if (sc_data && (sc_data[SC_HIDING].timer != -1 || // if the target is using a special hiding, i.e not using normal hiding/cloaking, don't bother
+ sc_data[SC_CLOAKING].timer != -1)) {
+ status_change_end( bl, SC_HIDING, -1);
+ status_change_end( bl, SC_CLOAKING, -1);
+ }
+ if(battle_check_target( src,bl, BCT_ENEMY ) > 0)
+ skill_attack(BF_MAGIC,src,src,bl,AL_RUWACH,sc_data[type].val1,tick,0);
+ }
+ break;
+ }
+ return 0;
+}
+
+
+static int status_calc_sigma(void)
+{
+ int i,j,k;
+
+ for(i=0;i<MAX_PC_CLASS;i++) {
+ memset(hp_sigma_val[i],0,sizeof(hp_sigma_val[i]));
+ for(k=0,j=2;j<=MAX_LEVEL;j++) {
+ k += hp_coefficient[i]*j + 50;
+ k -= k%100;
+ hp_sigma_val[i][j-1] = k;
+ }
+ }
+ return 0;
+}
+
+int status_readdb(void) {
+ int i,j,k;
+ FILE *fp;
+ char line[1024],*p;
+
+ // JOB•â³?’l‚P
+ fp=fopen("db/job_db1.txt","r");
+ if(fp==NULL){
+ printf("can't read db/job_db1.txt\n");
+ return 1;
+ }
+ i=0;
+ while(fgets(line, sizeof(line)-1, fp)){
+ char *split[50];
+ if(line[0]=='/' && line[1]=='/')
+ continue;
+ for(j=0,p=line;j<21 && p;j++){
+ split[j]=p;
+ p=strchr(p,',');
+ if(p) *p++=0;
+ }
+ if(j<21)
+ continue;
+ max_weight_base[i]=atoi(split[0]);
+ hp_coefficient[i]=atoi(split[1]);
+ hp_coefficient2[i]=atoi(split[2]);
+ sp_coefficient[i]=atoi(split[3]);
+ for(j=0;j<17;j++)
+ aspd_base[i][j]=atoi(split[j+4]);
+ i++;
+// -- moonsoul (below two lines added to accommodate high numbered new class ids)
+ if(i==24)
+ i=4001;
+ if(i==MAX_PC_CLASS)
+ break;
+ }
+ fclose(fp);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/job_db1.txt");
+ ShowStatus(tmp_output);
+
+ // JOBƒ{?ƒiƒX
+ memset(job_bonus,0,sizeof(job_bonus));
+ fp=fopen("db/job_db2.txt","r");
+ if(fp==NULL){
+ printf("can't read db/job_db2.txt\n");
+ return 1;
+ }
+ i=0;
+ while(fgets(line, sizeof(line)-1, fp)){
+ if(line[0]=='/' && line[1]=='/')
+ continue;
+ for(j=0,p=line;j<MAX_LEVEL && p;j++){
+ if(sscanf(p,"%d",&k)==0)
+ break;
+ job_bonus[0][i][j]=k;
+ job_bonus[2][i][j]=k; //—{ŽqE‚̃{?ƒiƒX‚Í•ª‚©‚ç‚È‚¢‚Ì‚Å?
+ p=strchr(p,',');
+ if(p) p++;
+ }
+ i++;
+// -- moonsoul (below two lines added to accommodate high numbered new class ids)
+ if(i==24)
+ i=4001;
+ if(i==MAX_PC_CLASS)
+ break;
+ }
+ fclose(fp);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/job_db2.txt");
+ ShowStatus(tmp_output);
+
+ // JOBƒ{?ƒiƒX2 ?¶E—p
+ fp=fopen("db/job_db2-2.txt","r");
+ if(fp==NULL){
+ printf("can't read db/job_db2-2.txt\n");
+ return 1;
+ }
+ i=0;
+ while(fgets(line, sizeof(line)-1, fp)){
+ if(line[0]=='/' && line[1]=='/')
+ continue;
+ for(j=0,p=line;j<MAX_LEVEL && p;j++){
+ if(sscanf(p,"%d",&k)==0)
+ break;
+ job_bonus[1][i][j]=k;
+ p=strchr(p,',');
+ if(p) p++;
+ }
+ i++;
+ if(i==MAX_PC_CLASS)
+ break;
+ }
+ fclose(fp);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/job_db2-2.txt");
+ ShowStatus(tmp_output);
+
+ // ƒTƒCƒY•ⳃe?ƒuƒ‹
+ for(i=0;i<3;i++)
+ for(j=0;j<20;j++)
+ atkmods[i][j]=100;
+ fp=fopen("db/size_fix.txt","r");
+ if(fp==NULL){
+ printf("can't read db/size_fix.txt\n");
+ return 1;
+ }
+ i=0;
+ while(fgets(line, sizeof(line)-1, fp)){
+ char *split[20];
+ if(line[0]=='/' && line[1]=='/')
+ continue;
+ if(atoi(line)<=0)
+ continue;
+ memset(split,0,sizeof(split));
+ for(j=0,p=line;j<20 && p;j++){
+ split[j]=p;
+ p=strchr(p,',');
+ if(p) *p++=0;
+ }
+ for(j=0;j<20 && split[j];j++)
+ atkmods[i][j]=atoi(split[j]);
+ i++;
+ }
+ fclose(fp);
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/size_fix.txt");
+ ShowStatus(tmp_output);
+
+ // ¸?ƒf?ƒ^ƒe?ƒuƒ‹
+ for(i=0;i<5;i++){
+ for(j=0;j<10;j++)
+ percentrefinery[i][j]=100;
+ refinebonus[i][0]=0;
+ refinebonus[i][1]=0;
+ refinebonus[i][2]=10;
+ }
+ fp=fopen("db/refine_db.txt","r");
+ if(fp==NULL){
+ printf("can't read db/refine_db.txt\n");
+ return 1;
+ }
+ i=0;
+ while(fgets(line, sizeof(line)-1, fp)){
+ char *split[16];
+ if(line[0]=='/' && line[1]=='/')
+ continue;
+ if(atoi(line)<=0)
+ continue;
+ memset(split,0,sizeof(split));
+ for(j=0,p=line;j<16 && p;j++){
+ split[j]=p;
+ p=strchr(p,',');
+ if(p) *p++=0;
+ }
+ refinebonus[i][0]=atoi(split[0]); // ¸?ƒ{?ƒiƒX
+ refinebonus[i][1]=atoi(split[1]); // ‰ß?¸?ƒ{?ƒiƒX
+ refinebonus[i][2]=atoi(split[2]); // ˆÀ‘S¸?ŒÀŠE
+ for(j=0;j<10 && split[j];j++)
+ percentrefinery[i][j]=atoi(split[j+3]);
+ i++;
+ }
+ fclose(fp); //Lupus. close this file!!!
+ sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/refine_db.txt");
+ ShowStatus(tmp_output);
+
+ return 0;
+}
+
+/*==========================================
+ * ƒXƒLƒ‹ŠÖŒW‰Šú‰»ˆ—
+ *------------------------------------------
+ */
+int do_init_status(void)
+{
+ add_timer_func_list(status_change_timer,"status_change_timer");
+ status_readdb();
+ status_calc_sigma();
+ return 0;
+}
diff --git a/src/map/status.h b/src/map/status.h
new file mode 100644
index 000000000..a07c47153
--- /dev/null
+++ b/src/map/status.h
@@ -0,0 +1,271 @@
+#ifndef _STATUS_H_
+#define _STATUS_H_
+
+enum { // struct map_session_data ‚Ì status_change‚Ì”Ô?ƒe?ƒuƒ‹
+// SC_SENDMAX–¢?‚̓Nƒ‰ƒCƒAƒ“ƒg‚Ö‚Ì’Ê’m‚ ‚èB
+// 2-2ŽŸE‚Ì’l‚͂Ȃñ‚©‚ß‚¿‚á‚­‚¿‚á‚Á‚Û‚¢‚̂Ŏb’èB‚½‚Ô‚ñ?X‚³‚ê‚Ü‚·B
+ SC_SENDMAX = 128, // note: max is now 182, but we'll need to do alot of moving around
+ SC_PROVOKE = 0,
+ SC_ENDURE = 1,
+ SC_TWOHANDQUICKEN = 2,
+ SC_CONCENTRATE = 3,
+ SC_HIDING = 4,
+ SC_CLOAKING = 5,
+ SC_ENCPOISON = 6,
+ SC_POISONREACT = 7,
+ SC_QUAGMIRE = 8,
+ SC_ANGELUS = 9,
+ SC_BLESSING = 10,
+ SC_SIGNUMCRUCIS = 11,
+ SC_INCREASEAGI = 12,
+ SC_DECREASEAGI = 13,
+ SC_SLOWPOISON = 14,
+ SC_IMPOSITIO = 15,
+ SC_SUFFRAGIUM = 16,
+ SC_ASPERSIO = 17,
+ SC_BENEDICTIO = 18,
+ SC_KYRIE = 19,
+ SC_MAGNIFICAT = 20,
+ SC_GLORIA = 21,
+ SC_AETERNA = 22,
+ SC_ADRENALINE = 23,
+ SC_WEAPONPERFECTION = 24,
+ SC_OVERTHRUST = 25,
+ SC_MAXIMIZEPOWER = 26,
+ SC_RIDING = 27,
+ SC_FALCON = 28,
+ SC_TRICKDEAD = 29,
+ SC_LOUD = 30,
+ SC_ENERGYCOAT = 31,
+ SC_BROKNARMOR = 32,
+ SC_BROKNWEAPON = 33,
+ SC_HALLUCINATION = 34,
+ SC_WEIGHT50 = 35,
+ SC_WEIGHT90 = 36,
+ SC_SPEEDPOTION0 = 37,
+ SC_SPEEDPOTION1 = 38,
+ SC_SPEEDPOTION2 = 39,
+ SC_SPEEDPOTION3 = 40,
+ SC_SPEEDUP0 = 41, // for skill speedup
+ SC_SPEEDUP1 = 42, // for skill speedup
+//-- 43-50
+ SC_STRIPWEAPON = 50,
+ SC_STRIPSHIELD = 51,
+ SC_STRIPARMOR = 52,
+ SC_STRIPHELM = 53,
+ SC_CP_WEAPON = 54,
+ SC_CP_SHIELD = 55,
+ SC_CP_ARMOR = 56,
+ SC_CP_HELM = 57,
+ SC_AUTOGUARD = 58,
+ SC_REFLECTSHIELD = 59,
+ SC_DEVOTION = 60,
+ SC_PROVIDENCE = 61,
+ SC_DEFENDER = 62,
+ SC_AUTOSPELL = 65,
+ SC_SPEARSQUICKEN = 68,
+//-- 69-85
+ SC_EXPLOSIONSPIRITS = 86,
+ SC_STEELBODY = 87,
+ SC_COMBO = 89,
+ SC_FLAMELAUNCHER = 90,
+ SC_FROSTWEAPON = 91,
+ SC_LIGHTNINGLOADER = 92,
+ SC_SEISMICWEAPON = 93,
+//-- 94-102
+ SC_AURABLADE = 103, /* ƒI?ƒ‰ƒuƒŒ?ƒh */
+ SC_PARRYING = 104, /* ƒpƒŠƒCƒ“ƒO */
+ SC_CONCENTRATION = 105, /* ƒRƒ“ƒZƒ“ƒgƒŒ?ƒVƒ‡ƒ“ */
+ SC_TENSIONRELAX = 106, /* ƒeƒ“ƒVƒ‡ƒ“ƒŠƒ‰ƒbƒNƒX */
+ SC_BERSERK = 107, /* ƒo?ƒT?ƒN */
+//-- 108, 109
+ SC_ASSUMPTIO = 110, /* ƒAƒVƒƒƒ“ƒvƒeƒBƒI */
+//-- 111, 112
+ SC_MAGICPOWER = 113, /* –‚–@—Í?• */
+ SC_EDP = 114, /* ƒGƒtƒFƒNƒg‚ª”»–¾‚µ‚½‚çˆÚ“® */
+ SC_TRUESIGHT = 115, /* ƒgƒDƒ‹?ƒTƒCƒg */
+ SC_WINDWALK = 116, /* ƒEƒCƒ“ƒhƒEƒH?ƒN */
+ SC_MELTDOWN = 117, /* ƒƒ‹ƒgƒ_ƒEƒ“ */
+ SC_CARTBOOST = 118, /* ƒJ?ƒgƒu?ƒXƒg */
+//-- 119
+ SC_REJECTSWORD = 120, /* ƒŠƒWƒFƒNƒgƒ\?ƒh */
+ SC_MARIONETTE = 121, /* ƒ}ƒŠƒIƒlƒbƒgƒRƒ“ƒgƒ?ƒ‹ */
+ SC_MARIONETTE2 = 122, // Marionette target
+//-- 123
+ SC_BLEEDING = 124, /* ƒwƒbƒhƒNƒ‰ƒbƒVƒ… */
+ SC_JOINTBEAT = 125, /* ƒWƒ‡ƒCƒ“ƒgƒr?ƒg */
+//-- 126, 127
+
+ SC_STONE = 128,
+ SC_FREEZE = 129,
+// <-- 130 = a baby skill status?
+ SC_STAN = 130,
+ SC_SLEEP = 131,
+// <-- 132 = another baby skill?
+ SC_POISON = 132,
+ SC_CURSE = 133,
+ SC_SILENCE = 134,
+ SC_CONFUSION = 135,
+ SC_BLIND = 136,
+ SC_DIVINA = SC_SILENCE,
+//-- 137-139
+ SC_SAFETYWALL = 140,
+ SC_PNEUMA = 141,
+//-- 142
+ SC_ANKLE = 143,
+ SC_DANCING = 144,
+ SC_KEEPING = 145,
+ SC_BARRIER = 146,
+//-- 147,148
+ SC_MAGICROD = 149,
+ SC_SIGHT = 150,
+ SC_RUWACH = 151,
+ SC_AUTOCOUNTER = 152,
+ SC_VOLCANO = 153,
+ SC_DELUGE = 154,
+ SC_VIOLENTGALE = 155,
+ SC_BLADESTOP_WAIT = 156,
+ SC_BLADESTOP = 157,
+ SC_EXTREMITYFIST = 158,
+//-- 159
+ SC_LULLABY =160,
+ SC_RICHMANKIM =161,
+ SC_ETERNALCHAOS =162,
+ SC_DRUMBATTLE =163,
+ SC_NIBELUNGEN =164,
+ SC_ROKISWEIL =165,
+ SC_INTOABYSS =166,
+ SC_SIEGFRIED =167,
+ SC_DISSONANCE =168,
+ SC_WHISTLE =169,
+ SC_ASSNCROS =170,
+ SC_POEMBRAGI =171,
+ SC_APPLEIDUN =172,
+ SC_UGLYDANCE =173,
+ SC_HUMMING =174,
+ SC_DONTFORGETME =175,
+ SC_FORTUNE =176,
+ SC_SERVICE4U =177,
+ SC_SPIDERWEB =180, /* ƒXƒpƒCƒ_?ƒEƒFƒbƒu */
+// <-- 181 = unknown status
+// <-- 182 = unknown status
+ SC_SACRIFICE =184, /* ƒTƒNƒŠƒtƒ@ƒCƒX */
+ SC_WEDDING =187, //Œ‹¥—p(Œ‹¥ˆßւɂȂÁ‚Ä?‚­‚Ì‚ª?‚¢‚Æ‚©)
+ SC_NOCHAT =188, //ÔƒGƒ‚?‘Ô
+ SC_SPLASHER =189, /* ƒxƒiƒ€ƒXƒvƒ‰ƒbƒVƒƒ? */
+ SC_SELFDESTRUCTION =190, /* Ž©”š */
+ SC_MEMORIZE =197, /* ƒƒ‚ƒ‰ƒCƒY */ // changed from 181 to 192
+ SC_DPOISON =198, /* –Ò“Å */
+
+// Used by English Team
+ SC_SLOWDOWN =45, // for skill slowdown
+ SC_AUTOBERSERK =46,
+ SC_SIGHTTRASHER =73,
+ SC_BASILICA =102, // temporarily use this before an actual id is found [celest]
+
+ SC_ENSEMBLE =159,
+ SC_FOGWALL =178,
+ SC_GOSPEL =179,
+ SC_PRESERVE =181,
+ SC_BATTLEORDERS =182,
+ SC_MOONLIT =183,
+ SC_ATKPOT =185, // [Valaris]
+ SC_MATKPOT =186, // [Valaris]
+ SC_MINDBREAKER =191,
+ SC_SPELLBREAKER =192,
+ SC_LANDPROTECTOR =193,
+ SC_ADAPTATION =194,
+ SC_CHASEWALK =195,
+ SC_REGENERATION =196,
+ SC_GUILDAURA =199,
+ SC_BABY =200,
+
+// Icons
+ _SC_BABY =200
+};
+extern int SkillStatusChangeTable[];
+
+extern int current_equip_item_index;
+
+// ƒpƒ‰ƒ[ƒ^Š“¾Œn battle.c ‚æ‚èˆÚ“®
+int status_get_class(struct block_list *bl);
+int status_get_dir(struct block_list *bl);
+int status_get_lv(struct block_list *bl);
+int status_get_range(struct block_list *bl);
+int status_get_hp(struct block_list *bl);
+int status_get_max_hp(struct block_list *bl);
+int status_get_str(struct block_list *bl);
+int status_get_agi(struct block_list *bl);
+int status_get_vit(struct block_list *bl);
+int status_get_int(struct block_list *bl);
+int status_get_dex(struct block_list *bl);
+int status_get_luk(struct block_list *bl);
+int status_get_hit(struct block_list *bl);
+int status_get_flee(struct block_list *bl);
+int status_get_def(struct block_list *bl);
+int status_get_mdef(struct block_list *bl);
+int status_get_flee2(struct block_list *bl);
+int status_get_def2(struct block_list *bl);
+int status_get_mdef2(struct block_list *bl);
+int status_get_baseatk(struct block_list *bl);
+int status_get_atk(struct block_list *bl);
+int status_get_atk2(struct block_list *bl);
+int status_get_speed(struct block_list *bl);
+int status_get_adelay(struct block_list *bl);
+int status_get_amotion(struct block_list *bl);
+int status_get_dmotion(struct block_list *bl);
+int status_get_element(struct block_list *bl);
+int status_get_attack_element(struct block_list *bl);
+int status_get_attack_element2(struct block_list *bl); //¶Žè•Ší‘®«Žæ“¾
+#define status_get_elem_type(bl) (status_get_element(bl)%10)
+#define status_get_elem_level(bl) (status_get_element(bl)/10/2)
+int status_get_party_id(struct block_list *bl);
+int status_get_guild_id(struct block_list *bl);
+int status_get_race(struct block_list *bl);
+int status_get_size(struct block_list *bl);
+int status_get_mode(struct block_list *bl);
+int status_get_mexp(struct block_list *bl);
+int status_get_race2(struct block_list *bl);
+
+struct status_change *status_get_sc_data(struct block_list *bl);
+short *status_get_sc_count(struct block_list *bl);
+short *status_get_opt1(struct block_list *bl);
+short *status_get_opt2(struct block_list *bl);
+short *status_get_opt3(struct block_list *bl);
+short *status_get_option(struct block_list *bl);
+
+int status_get_matk1(struct block_list *bl);
+int status_get_matk2(struct block_list *bl);
+int status_get_critical(struct block_list *bl);
+int status_get_atk_(struct block_list *bl);
+int status_get_atk_2(struct block_list *bl);
+int status_get_atk2(struct block_list *bl);
+
+int status_isdead(struct block_list *bl);
+
+int status_get_sc_def(struct block_list *bl, int type);
+#define status_get_sc_def_mdef(bl) (status_get_sc_def(bl, SP_MDEF1))
+#define status_get_sc_def_vit(bl) (status_get_sc_def(bl, SP_DEF2))
+#define status_get_sc_def_int(bl) (status_get_sc_def(bl, SP_MDEF2))
+#define status_get_sc_def_luk(bl) (status_get_sc_def(bl, SP_LUK))
+
+// ó‘ÔˆÙíŠÖ˜A skill.c ‚æ‚èˆÚ“®
+int status_change_start(struct block_list *bl,int type,int val1,int val2,int val3,int val4,int tick,int flag);
+int status_change_end( struct block_list* bl , int type,int tid );
+int status_change_timer(int tid, unsigned int tick, int id, int data);
+int status_change_timer_sub(struct block_list *bl, va_list ap );
+int status_change_clear(struct block_list *bl,int type);
+
+// ƒXƒe[ƒ^ƒXŒvŽZ pc.c ‚©‚番—£
+// pc_calcstatus
+int status_calc_pc(struct map_session_data* sd,int first);
+int status_calc_speed(struct map_session_data*); // [Celest]
+// int status_calc_skilltree(struct map_session_data *sd);
+int status_getrefinebonus(int lv,int type);
+int status_percentrefinery(struct map_session_data *sd,struct item *item);
+extern int percentrefinery[5][10];
+
+int status_readdb(void);
+int do_init_status(void);
+
+#endif
diff --git a/src/map/storage.c b/src/map/storage.c
index fc6f63cdd..82ecd9321 100644
--- a/src/map/storage.c
+++ b/src/map/storage.c
@@ -3,14 +3,18 @@
#include <stdlib.h>
#include <string.h>
-#include "db.h"
+#include "../common/db.h"
+#include "../common/nullpo.h"
+#include "../common/malloc.h"
+
#include "itemdb.h"
#include "clif.h"
#include "intif.h"
#include "pc.h"
#include "storage.h"
#include "guild.h"
-#include "nullpo.h"
+#include "battle.h"
+#include "atcommand.h"
#ifdef MEMWATCH
#include "memwatch.h"
@@ -42,13 +46,13 @@ struct item *i2=(struct item *)_i2;
void sortage_sortitem(struct storage* stor){
nullpo_retv(stor);
- qsort(stor->storage, MAX_STORAGE, sizeof(struct item), storage_comp_item);
+ qsort(stor->storage_, MAX_STORAGE, sizeof(struct item), storage_comp_item);
}
void sortage_gsortitem(struct guild_storage* gstor){
nullpo_retv(gstor);
- qsort(gstor->storage, MAX_GUILD_STORAGE, sizeof(struct item), storage_comp_item);
+ qsort(gstor->storage_, MAX_GUILD_STORAGE, sizeof(struct item), storage_comp_item);
}
/*==========================================
@@ -61,17 +65,32 @@ int do_init_storage(void) // map.c::do_init()‚©‚çŒÄ‚΂ê‚é
guild_storage_db=numdb_init();
return 1;
}
-
-void do_final_storage(void) // map.c::do_final()‚©‚çŒÄ‚΂ê‚é
+static int guild_storage_db_final(void *key,void *data,va_list ap)
+{
+ struct guild_storage *gstor=(struct guild_storage *) data;
+ aFree(gstor);
+ return 0;
+}
+static int storage_db_final(void *key,void *data,va_list ap)
{
+ struct storage *stor=(struct storage *) data;
+ aFree(stor);
+ return 0;
+}
+void do_final_storage(void) // by [MC Cameri]
+{
+ if (storage_db)
+ numdb_final(storage_db,storage_db_final);
+ if (guild_storage_db)
+ numdb_final(guild_storage_db,guild_storage_db_final);
}
struct storage *account2storage(int account_id)
{
struct storage *stor;
- stor=numdb_search(storage_db,account_id);
+ stor=(struct storage *) numdb_search(storage_db,account_id);
if(stor == NULL) {
- stor = calloc(sizeof(struct storage), 1);
+ stor = (struct storage *) aCallocA(sizeof(struct storage), 1);
if(stor == NULL){
printf("storage: out of memory!\n");
exit(0);
@@ -85,15 +104,15 @@ struct storage *account2storage(int account_id)
// Just to ask storage, without creation
struct storage *account2storage2(int account_id) {
- return numdb_search(storage_db, account_id);
+ return (struct storage *) numdb_search(storage_db, account_id);
}
int storage_delete(int account_id)
{
- struct storage *stor = numdb_search(storage_db,account_id);
+ struct storage *stor = (struct storage *) numdb_search(storage_db,account_id);
if(stor) {
numdb_erase(storage_db,account_id);
- free(stor);
+ aFree(stor);
}
return 0;
}
@@ -108,38 +127,25 @@ int storage_storageopen(struct map_session_data *sd)
nullpo_retr(0, sd);
- if((stor = numdb_search(storage_db,sd->status.account_id)) != NULL) {
- stor->storage_status = 1;
- sd->state.storage_flag = 0;
- clif_storageitemlist(sd,stor);
- clif_storageequiplist(sd,stor);
- clif_updatestorageamount(sd,stor);
- return 0;
+ if(pc_isGM(sd) && pc_isGM(sd) < battle_config.gm_can_drop_lv) {
+ clif_displaymessage(sd->fd, msg_txt(246));
+ return 1;
+ }
+ if((stor = (struct storage *) numdb_search(storage_db,sd->status.account_id)) != NULL) {
+ if (stor->storage_status == 0) {
+ stor->storage_status = 1;
+ sd->state.storage_flag = 0;
+ clif_storageitemlist(sd,stor);
+ clif_storageequiplist(sd,stor);
+ clif_updatestorageamount(sd,stor);
+ return 0;
+ }
} else
intif_request_storage(sd->status.account_id);
return 1;
}
-int storage_storageopen2(struct map_session_data *sd, struct map_session_data *pl_sd)
-{
- struct storage *stor;
- if(sd == NULL || pl_sd == NULL)
- {
- printf("storage_storageopen nullpo\n");
- return 0;
- }
-
- if((stor = numdb_search(storage_db,pl_sd->status.account_id)) != NULL)
- {
- clif_storageitemlist(sd,stor);
- clif_storageequiplist(sd,stor);
- clif_updatestorageamount(sd,stor);
- return 1;
- }
- return 0;
-}
-
/*==========================================
* ƒJƒvƒ‰‘qŒÉ‚ÖƒAƒCƒeƒ€’ljÁ
*------------------------------------------
@@ -153,6 +159,8 @@ int storage_additem(struct map_session_data *sd,struct storage *stor,struct item
nullpo_retr(1, stor);
nullpo_retr(1, item_data);
+ stor->dirty = 1;
+
if(item_data->nameid <= 0 || amount <= 0)
return 1;
nullpo_retr(1, data = itemdb_search(item_data->nameid));
@@ -161,12 +169,10 @@ int storage_additem(struct map_session_data *sd,struct storage *stor,struct item
if(!itemdb_isequip2(data)){
// ‘•”õ•i‚ł͂Ȃ¢‚Ì‚ÅAŠùŠ—L•i‚È‚çŒÂ”‚̂ݕω»‚³‚¹‚é
for(i=0;i<MAX_STORAGE;i++){
- if(stor->storage[i].nameid == item_data->nameid &&
- stor->storage[i].card[0] == item_data->card[0] && stor->storage[i].card[1] == item_data->card[1] &&
- stor->storage[i].card[2] == item_data->card[2] && stor->storage[i].card[3] == item_data->card[3]){
- if(stor->storage[i].amount+amount > MAX_AMOUNT)
+ if( compare_item (&stor->storage_[i], item_data)) {
+ if(stor->storage_[i].amount+amount > MAX_AMOUNT)
return 1;
- stor->storage[i].amount+=amount;
+ stor->storage_[i].amount+=amount;
clif_storageitemadded(sd,stor,i,amount);
break;
}
@@ -175,9 +181,9 @@ int storage_additem(struct map_session_data *sd,struct storage *stor,struct item
if(i>=MAX_STORAGE){
// ‘•”õ•i‚©–¢Š—L•i‚¾‚Á‚½‚̂ŋ󂫗“‚֒ljÁ
for(i=0;i<MAX_STORAGE;i++){
- if(stor->storage[i].nameid==0){
- memcpy(&stor->storage[i],item_data,sizeof(stor->storage[0]));
- stor->storage[i].amount=amount;
+ if(stor->storage_[i].nameid==0){
+ memcpy(&stor->storage_[i],item_data,sizeof(stor->storage_[0]));
+ stor->storage_[i].amount=amount;
stor->storage_amount++;
clif_storageitemadded(sd,stor,i,amount);
clif_updatestorageamount(sd,stor);
@@ -187,6 +193,7 @@ int storage_additem(struct map_session_data *sd,struct storage *stor,struct item
if(i>=MAX_STORAGE)
return 1;
}
+
return 0;
}
/*==========================================
@@ -198,17 +205,19 @@ int storage_delitem(struct map_session_data *sd,struct storage *stor,int n,int a
nullpo_retr(1, sd);
nullpo_retr(1, stor);
- if(stor->storage[n].nameid==0 || stor->storage[n].amount<amount)
+ if(stor->storage_[n].nameid==0 || stor->storage_[n].amount<amount)
return 1;
- stor->storage[n].amount-=amount;
- if(stor->storage[n].amount==0){
- memset(&stor->storage[n],0,sizeof(stor->storage[0]));
+ stor->storage_[n].amount-=amount;
+ if(stor->storage_[n].amount==0){
+ memset(&stor->storage_[n],0,sizeof(stor->storage_[0]));
stor->storage_amount--;
clif_updatestorageamount(sd,stor);
}
clif_storageitemremoved(sd,n,amount);
+ stor->dirty = 1;
+
return 0;
}
/*==========================================
@@ -220,15 +229,16 @@ int storage_storageadd(struct map_session_data *sd,int index,int amount)
struct storage *stor;
nullpo_retr(0, sd);
- nullpo_retr(0, stor=account2storage(sd->status.account_id));
+ nullpo_retr(0, stor=account2storage2(sd->status.account_id));
if( (stor->storage_amount <= MAX_STORAGE) && (stor->storage_status == 1) ) { // storage not full & storage open
if(index>=0 && index<MAX_INVENTORY) { // valid index
- if( (amount <= sd->status.inventory[index].amount) && (amount > 0) ) { //valid amount
- if(storage_additem(sd,stor,&sd->status.inventory[index],amount)==0)
- // remove item from inventory
- pc_delitem(sd,index,amount,0);
- } // valid amount
+ if( (amount <= sd->status.inventory[index].amount) && (amount > 0) ) { //valid amount
+// log_tostorage(sd, index, 0);
+ if(storage_additem(sd,stor,&sd->status.inventory[index],amount)==0)
+ // remove item from inventory
+ pc_delitem(sd,index,amount,0);
+ } // valid amount
}// valid index
}// storage not full & storage open
@@ -245,15 +255,16 @@ int storage_storageget(struct map_session_data *sd,int index,int amount)
int flag;
nullpo_retr(0, sd);
- nullpo_retr(0, stor=account2storage(sd->status.account_id));
+ nullpo_retr(0, stor=account2storage2(sd->status.account_id));
if(stor->storage_status == 1) { // storage open
if(index>=0 && index<MAX_STORAGE) { // valid index
- if( (amount <= stor->storage[index].amount) && (amount > 0) ) { //valid amount
- if((flag = pc_additem(sd,&stor->storage[index],amount)) == 0)
+ if( (amount <= stor->storage_[index].amount) && (amount > 0) ) { //valid amount
+ if((flag = pc_additem(sd,&stor->storage_[index],amount)) == 0)
storage_delitem(sd,stor,index,amount);
else
clif_additem(sd,0,0,flag);
+// log_fromstorage(sd, index, 0);
} // valid amount
}// valid index
}// storage open
@@ -269,7 +280,7 @@ int storage_storageaddfromcart(struct map_session_data *sd,int index,int amount)
struct storage *stor;
nullpo_retr(0, sd);
- nullpo_retr(0, stor=account2storage(sd->status.account_id));
+ nullpo_retr(0, stor=account2storage2(sd->status.account_id));
if( (stor->storage_amount <= MAX_STORAGE) && (stor->storage_status == 1) ) { // storage not full & storage open
if(index>=0 && index<MAX_INVENTORY) { // valid index
@@ -292,12 +303,12 @@ int storage_storagegettocart(struct map_session_data *sd,int index,int amount)
struct storage *stor;
nullpo_retr(0, sd);
- nullpo_retr(0, stor=account2storage(sd->status.account_id));
+ nullpo_retr(0, stor=account2storage2(sd->status.account_id));
if(stor->storage_status == 1) { // storage open
if(index>=0 && index<MAX_STORAGE) { // valid index
- if( (amount <= stor->storage[index].amount) && (amount > 0) ) { //valid amount
- if(pc_cart_additem(sd,&stor->storage[index],amount)==0){
+ if( (amount <= stor->storage_[index].amount) && (amount > 0) ) { //valid amount
+ if(pc_cart_additem(sd,&stor->storage_[index],amount)==0){
storage_delitem(sd,stor,index,amount);
}
} // valid amount
@@ -317,12 +328,14 @@ int storage_storageclose(struct map_session_data *sd)
struct storage *stor;
nullpo_retr(0, sd);
- nullpo_retr(0, stor=account2storage(sd->status.account_id));
+ nullpo_retr(0, stor=account2storage2(sd->status.account_id));
stor->storage_status=0;
sd->state.storage_flag = 0;
clif_storageclose(sd);
+ storage_storage_save(sd);
+
sortage_sortitem(stor);
return 0;
}
@@ -337,20 +350,36 @@ int storage_storage_quit(struct map_session_data *sd)
nullpo_retr(0, sd);
- stor = numdb_search(storage_db,sd->status.account_id);
- if(stor) stor->storage_status = 0;
+ stor = (struct storage *) numdb_search(storage_db,sd->status.account_id);
+ if(stor) {
+ stor->storage_status = 0;
+ storage_storage_save(sd);
+ }
return 0;
}
+void storage_storage_dirty(struct map_session_data *sd)
+{
+ struct storage *stor;
+
+ stor=(struct storage *) numdb_search(storage_db,sd->status.account_id);
+
+ if(stor)
+ stor->dirty = 1;
+}
+
int storage_storage_save(struct map_session_data *sd)
{
struct storage *stor;
nullpo_retr(0, sd);
- stor=numdb_search(storage_db,sd->status.account_id);
- if(stor) intif_send_storage(stor);
+ stor=(struct storage *) numdb_search(storage_db,sd->status.account_id);
+ if(stor && stor->dirty) {
+ intif_send_storage(stor);
+ stor->dirty = 0;
+ }
return 0;
}
@@ -359,9 +388,9 @@ struct guild_storage *guild2storage(int guild_id)
{
struct guild_storage *gs = NULL;
if(guild_search(guild_id) != NULL) {
- gs=numdb_search(guild_storage_db,guild_id);
+ gs=(struct guild_storage *) numdb_search(guild_storage_db,guild_id);
if(gs == NULL) {
- gs = calloc(sizeof(struct guild_storage), 1);
+ gs = (struct guild_storage *) aCallocA(sizeof(struct guild_storage), 1);
if(gs==NULL){
printf("storage: out of memory!\n");
exit(0);
@@ -375,10 +404,10 @@ struct guild_storage *guild2storage(int guild_id)
int guild_storage_delete(int guild_id)
{
- struct guild_storage *gstor = numdb_search(guild_storage_db,guild_id);
+ struct guild_storage *gstor = (struct guild_storage *) numdb_search(guild_storage_db,guild_id);
if(gstor) {
numdb_erase(guild_storage_db,guild_id);
- free(gstor);
+ aFree(gstor);
}
return 0;
}
@@ -391,7 +420,7 @@ int storage_guild_storageopen(struct map_session_data *sd)
if(sd->status.guild_id <= 0)
return 2;
- if((gstor = numdb_search(guild_storage_db,sd->status.guild_id)) != NULL) {
+ if((gstor = (struct guild_storage *) numdb_search(guild_storage_db,sd->status.guild_id)) != NULL) {
if(gstor->storage_status)
return 1;
gstor->storage_status = 1;
@@ -427,12 +456,10 @@ int guild_storage_additem(struct map_session_data *sd,struct guild_storage *stor
if(!itemdb_isequip2(data)){
// ‘•”õ•i‚ł͂Ȃ¢‚Ì‚ÅAŠùŠ—L•i‚È‚çŒÂ”‚̂ݕω»‚³‚¹‚é
for(i=0;i<MAX_GUILD_STORAGE;i++){
- if(stor->storage[i].nameid == item_data->nameid &&
- stor->storage[i].card[0] == item_data->card[0] && stor->storage[i].card[1] == item_data->card[1] &&
- stor->storage[i].card[2] == item_data->card[2] && stor->storage[i].card[3] == item_data->card[3]){
- if(stor->storage[i].amount+amount > MAX_AMOUNT)
+ if(compare_item(&stor->storage_[i], item_data)) {
+ if(stor->storage_[i].amount+amount > MAX_AMOUNT)
return 1;
- stor->storage[i].amount+=amount;
+ stor->storage_[i].amount+=amount;
clif_guildstorageitemadded(sd,stor,i,amount);
break;
}
@@ -441,9 +468,9 @@ int guild_storage_additem(struct map_session_data *sd,struct guild_storage *stor
if(i>=MAX_GUILD_STORAGE){
// ‘•”õ•i‚©–¢Š—L•i‚¾‚Á‚½‚̂ŋ󂫗“‚֒ljÁ
for(i=0;i<MAX_GUILD_STORAGE;i++){
- if(stor->storage[i].nameid==0){
- memcpy(&stor->storage[i],item_data,sizeof(stor->storage[0]));
- stor->storage[i].amount=amount;
+ if(stor->storage_[i].nameid==0){
+ memcpy(&stor->storage_[i],item_data,sizeof(stor->storage_[0]));
+ stor->storage_[i].amount=amount;
stor->storage_amount++;
clif_guildstorageitemadded(sd,stor,i,amount);
clif_updateguildstorageamount(sd,stor);
@@ -461,12 +488,12 @@ int guild_storage_delitem(struct map_session_data *sd,struct guild_storage *stor
nullpo_retr(1, sd);
nullpo_retr(1, stor);
- if(stor->storage[n].nameid==0 || stor->storage[n].amount<amount)
+ if(stor->storage_[n].nameid==0 || stor->storage_[n].amount<amount)
return 1;
- stor->storage[n].amount-=amount;
- if(stor->storage[n].amount==0){
- memset(&stor->storage[n],0,sizeof(stor->storage[0]));
+ stor->storage_[n].amount-=amount;
+ if(stor->storage_[n].amount==0){
+ memset(&stor->storage_[n],0,sizeof(stor->storage_[0]));
stor->storage_amount--;
clif_updateguildstorageamount(sd,stor);
}
@@ -485,6 +512,7 @@ int storage_guild_storageadd(struct map_session_data *sd,int index,int amount)
if( (stor->storage_amount <= MAX_GUILD_STORAGE) && (stor->storage_status == 1) ) { // storage not full & storage open
if(index>=0 && index<MAX_INVENTORY) { // valid index
if( (amount <= sd->status.inventory[index].amount) && (amount > 0) ) { //valid amount
+// log_tostorage(sd, index, 1);
if(guild_storage_additem(sd,stor,&sd->status.inventory[index],amount)==0)
// remove item from inventory
pc_delitem(sd,index,amount,0);
@@ -506,11 +534,12 @@ int storage_guild_storageget(struct map_session_data *sd,int index,int amount)
if((stor=guild2storage(sd->status.guild_id)) != NULL) {
if(stor->storage_status == 1) { // storage open
if(index>=0 && index<MAX_GUILD_STORAGE) { // valid index
- if( (amount <= stor->storage[index].amount) && (amount > 0) ) { //valid amount
- if((flag = pc_additem(sd,&stor->storage[index],amount)) == 0)
+ if( (amount <= stor->storage_[index].amount) && (amount > 0) ) { //valid amount
+ if((flag = pc_additem(sd,&stor->storage_[index],amount)) == 0)
guild_storage_delitem(sd,stor,index,amount);
else
clif_additem(sd,0,0,flag);
+// log_fromstorage(sd, index, 1);
} // valid amount
}// valid index
}// storage open
@@ -548,8 +577,8 @@ int storage_guild_storagegettocart(struct map_session_data *sd,int index,int amo
if((stor=guild2storage(sd->status.guild_id)) != NULL) {
if(stor->storage_status == 1) { // storage open
if(index>=0 && index<MAX_GUILD_STORAGE) { // valid index
- if( (amount <= stor->storage[index].amount) && (amount > 0) ) { //valid amount
- if(pc_cart_additem(sd,&stor->storage[index],amount)==0){
+ if( (amount <= stor->storage_[index].amount) && (amount > 0) ) { //valid amount
+ if(pc_cart_additem(sd,&stor->storage_[index],amount)==0){
guild_storage_delitem(sd,stor,index,amount);
}
} // valid amount
@@ -583,7 +612,7 @@ int storage_guild_storage_quit(struct map_session_data *sd,int flag)
nullpo_retr(0, sd);
- stor = numdb_search(guild_storage_db,sd->status.guild_id);
+ stor = (struct guild_storage *) numdb_search(guild_storage_db,sd->status.guild_id);
if(stor) {
if(!flag)
intif_send_guild_storage(sd->status.account_id,stor);
diff --git a/src/map/storage.h b/src/map/storage.h
index 352dee4f0..7b2ac2cbe 100644
--- a/src/map/storage.h
+++ b/src/map/storage.h
@@ -5,7 +5,6 @@
#include "mmo.h"
int storage_storageopen(struct map_session_data *sd);
-int storage_storageopen2(struct map_session_data *sd,struct map_session_data *pl_sd);
int storage_storageadd(struct map_session_data *sd,int index,int amount);
int storage_storageget(struct map_session_data *sd,int index,int amount);
int storage_storageaddfromcart(struct map_session_data *sd,int index,int amount);
@@ -18,6 +17,7 @@ struct storage *account2storage2(int account_id);
int storage_delete(int account_id);
int storage_storage_quit(struct map_session_data *sd);
int storage_storage_save(struct map_session_data *sd);
+void storage_storage_dirty(struct map_session_data *sd);
struct guild_storage *guild2storage(int guild_id);
int guild_storage_delete(int guild_id);
diff --git a/src/map/trade.c b/src/map/trade.c
index 9d2128690..eb1d45ba2 100644
--- a/src/map/trade.c
+++ b/src/map/trade.c
@@ -1,6 +1,10 @@
+// $Id: trade.c 375 2005-03-04 21:33:31Z Yor $
+//#include <config.h>
+
#include <stdio.h>
#include <string.h>
+#include "../common/nullpo.h"
#include "clif.h"
#include "itemdb.h"
#include "map.h"
@@ -8,44 +12,46 @@
#include "pc.h"
#include "npc.h"
#include "battle.h"
-#include "nullpo.h"
+#include "chrif.h"
+#include "storage.h"
+#include "intif.h"
+#include "atcommand.h"
#include "log.h"
/*==========================================
* Žæˆø—v¿‚𑊎è‚É‘—‚é
*------------------------------------------
*/
-void trade_traderequest(struct map_session_data *sd,int target_id)
-{
+void trade_traderequest(struct map_session_data *sd, int target_id) {
struct map_session_data *target_sd;
nullpo_retv(sd);
- if((target_sd = map_id2sd(target_id)) != NULL){
- if(!battle_config.invite_request_check) {
- if(target_sd->guild_invite>0 || target_sd->party_invite>0){
- clif_tradestart(sd,2); // ‘ŠŽè‚ÍPT—v¿’†‚©Guild—v¿’†
+ if ((target_sd = map_id2sd(target_id)) != NULL) {
+ if (!battle_config.invite_request_check) {
+ if (target_sd->guild_invite > 0 || target_sd->party_invite > 0) {
+ clif_tradestart(sd, 2); // ‘ŠŽè‚ÍPT—v¿’†‚©Guild—v¿’†
return;
}
}
- if((target_sd->trade_partner !=0) || (sd->trade_partner !=0)) {
- trade_tradecancel(sd); //person is in another trade
- }
- else{
- if((pc_isGM(sd) < 60) && (sd->bl.m != target_sd->bl.m
- || (sd->bl.x - target_sd->bl.x <= -5 || sd->bl.x - target_sd->bl.x >= 5)
- || (sd->bl.y - target_sd->bl.y <= -5 || sd->bl.y - target_sd->bl.y >= 5))) {
- clif_tradestart(sd,0); //too far
- }
- else if(sd!=target_sd) {
+ if(pc_isGM(sd) && pc_isGM(target_sd) < battle_config.gm_can_drop_lv) {
+ clif_displaymessage(sd->fd, msg_txt(246));
+ trade_tradecancel(sd); // GM is not allowed to trade
+ } else if ((target_sd->trade_partner != 0) || (sd->trade_partner != 0)) {
+ trade_tradecancel(sd); // person is in another trade
+ } else {
+ if (!pc_isGM(sd) && (sd->bl.m != target_sd->bl.m ||
+ (sd->bl.x - target_sd->bl.x <= -5 || sd->bl.x - target_sd->bl.x >= 5) ||
+ (sd->bl.y - target_sd->bl.y <= -5 || sd->bl.y - target_sd->bl.y >= 5))) {
+ clif_tradestart(sd, 0); // too far
+ } else if (sd != target_sd) {
target_sd->trade_partner = sd->status.account_id;
sd->trade_partner = target_sd->status.account_id;
- clif_traderequest(target_sd,sd->status.name);
+ clif_traderequest(target_sd, sd->status.name);
}
}
- }
- else{
- clif_tradestart(sd,1); //character does not exist
+ } else {
+ clif_tradestart(sd, 1); // character does not exist
}
}
@@ -53,34 +59,103 @@ void trade_traderequest(struct map_session_data *sd,int target_id)
* Žæˆø—v¿
*------------------------------------------
*/
-void trade_tradeack(struct map_session_data *sd,int type)
-{
+void trade_tradeack(struct map_session_data *sd, int type) {
struct map_session_data *target_sd;
-
+ struct storage *stor;
nullpo_retv(sd);
- if((target_sd = map_id2sd(sd->trade_partner)) != NULL){
- clif_tradestart(target_sd,type);
- clif_tradestart(sd,type);
- if(type == 4){ // Cancel
- sd->deal_locked =0;
- sd->trade_partner=0;
- target_sd->deal_locked=0;
- target_sd->trade_partner=0;
+ if ((target_sd = map_id2sd(sd->trade_partner)) != NULL) {
+ clif_tradestart(target_sd, type);
+ clif_tradestart(sd, type);
+ if (type == 4) { // Cancel
+ sd->deal_locked = 0;
+ sd->trade_partner = 0;
+ target_sd->deal_locked = 0;
+ target_sd->trade_partner = 0;
}
- if(sd->npc_id != 0)
+ if (sd->npc_id != 0)
npc_event_dequeue(sd);
- if(target_sd->npc_id != 0)
+ if (target_sd->npc_id != 0)
npc_event_dequeue(target_sd);
+
+ //close STORAGE window if it's open. It protects from spooffing packets [Lupus]
+ stor=account2storage2(sd->status.account_id);
+ if(stor!=NULL && stor->storage_status == 1) {
+ if (sd->state.storage_flag) //is it Guild Storage or Common
+ storage_guild_storageclose(sd);
+ else
+ storage_storageclose(sd);
+ }//END OF STORAGE CLOSE
}
}
/*==========================================
+ * Check here hacker for duplicate item in trade
+ * normal client refuse to have 2 same types of item (except equipment) in same trade window
+ * normal client authorise only no equiped item and only from inventory
+ *------------------------------------------
+ */
+int impossible_trade_check(struct map_session_data *sd) {
+ struct item inventory[MAX_INVENTORY];
+ char message_to_gm[200];
+ int i, index;
+
+ nullpo_retr(0, sd);
+
+ // get inventory of player
+ memcpy(&inventory, &sd->status.inventory, sizeof(struct item) * MAX_INVENTORY);
+
+/* remove this part: arrows can be trade and equiped
+ // remove equiped items (they can not be trade)
+ for (i = 0; i < MAX_INVENTORY; i++)
+ if (inventory[i].nameid > 0 && inventory[i].equip)
+ memset(&inventory[i], 0, sizeof(struct item));
+*/
+
+ // check items in player inventory
+ for(i = 0; i < 10; i++)
+ if (sd->deal_item_amount[i] < 0) { // negativ? -> hack
+// printf("Negativ amount in trade, by hack!\n"); // normal client send cancel when we type negativ amount
+ return -1;
+ } else if (sd->deal_item_amount[i] > 0) {
+ index = sd->deal_item_index[i] - 2;
+ inventory[index].amount -= sd->deal_item_amount[i]; // remove item from inventory
+// printf("%d items left\n", inventory[index].amount);
+ if (inventory[index].amount < 0) { // if more than the player have -> hack
+// printf("A player try to trade more items that he has: hack!\n");
+ sprintf(message_to_gm, msg_txt(538), sd->status.name, sd->status.account_id); // Hack on trade: character '%s' (account: %d) try to trade more items that he has.
+ intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message_to_gm);
+ sprintf(message_to_gm, msg_txt(539), sd->status.inventory[index].amount, sd->status.inventory[index].nameid, sd->status.inventory[index].amount - inventory[index].amount); // This player has %d of a kind of item (id: %d), and try to trade %d of them.
+ intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message_to_gm);
+ // if we block people
+ if (battle_config.ban_hack_trade < 0) {
+ chrif_char_ask_name(-1, sd->status.name, 1, 0, 0, 0, 0, 0, 0); // type: 1 - block
+ clif_setwaitclose(sd->fd); // forced to disconnect because of the hack
+ // message about the ban
+ sprintf(message_to_gm, msg_txt(540), battle_config.ban_spoof_namer); // This player has been definitivly blocked.
+ // if we ban people
+ } else if (battle_config.ban_hack_trade > 0) {
+ chrif_char_ask_name(-1, sd->status.name, 2, 0, 0, 0, 0, battle_config.ban_hack_trade, 0); // type: 2 - ban (year, month, day, hour, minute, second)
+ clif_setwaitclose(sd->fd); // forced to disconnect because of the hack
+ // message about the ban
+ sprintf(message_to_gm, msg_txt(507), battle_config.ban_spoof_namer); // This player has been banned for %d minute(s).
+ } else {
+ // message about the ban
+ sprintf(message_to_gm, msg_txt(508)); // This player hasn't been banned (Ban option is disabled).
+ }
+ intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message_to_gm);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/*==========================================
* ƒAƒCƒeƒ€’ljÁ
*------------------------------------------
*/
-void trade_tradeadditem(struct map_session_data *sd, int index, int amount)
-{
+void trade_tradeadditem(struct map_session_data *sd, int index, int amount) {
struct map_session_data *target_sd;
int trade_i;
int trade_weight = 0;
@@ -89,7 +164,7 @@ void trade_tradeadditem(struct map_session_data *sd, int index, int amount)
nullpo_retv(sd);
if (((target_sd = map_id2sd(sd->trade_partner)) != NULL) && (sd->deal_locked < 1)){
- if (index < 2 || index >= MAX_INVENTORY + 2){
+ if (index < 2 || index >= MAX_INVENTORY + 2) {
if (index == 0) {
if (amount > 0 && amount <= MAX_ZENY && amount <= sd->status.zeny && // check amount
(target_sd->status.zeny + amount) <= MAX_ZENY) { // fix positiv overflow
@@ -108,7 +183,7 @@ void trade_tradeadditem(struct map_session_data *sd, int index, int amount)
trade_weight += sd->inventory_data[index-2]->weight * amount;
if (target_sd->weight + trade_weight > target_sd->max_weight){
clif_tradeitemok(sd, index, 1); // fail to add item -- the player was over weighted.
- amount = 0; // [MouseJstr]
+ amount = 0;
} else {
for(c = 0; c == trade_i - 1; c++) { // re-deal exploit protection [Valaris]
if (sd->deal_item_index[c] == index) {
@@ -118,6 +193,10 @@ void trade_tradeadditem(struct map_session_data *sd, int index, int amount)
}
sd->deal_item_index[trade_i] = index;
sd->deal_item_amount[trade_i] += amount;
+ if (impossible_trade_check(sd)) { // check exploit (trade more items that you have)
+ trade_tradecancel(sd);
+ return;
+ }
clif_tradeitemok(sd, index, 0); // success to add item
clif_tradeadditem(sd, target_sd, index, amount);
}
@@ -134,27 +213,39 @@ void trade_tradeadditem(struct map_session_data *sd, int index, int amount)
* ƒAƒCƒeƒ€’ljÁŠ®—¹(ok‰Ÿ‚µ)
*------------------------------------------
*/
-void trade_tradeok(struct map_session_data *sd)
-{
+void trade_tradeok(struct map_session_data *sd) {
struct map_session_data *target_sd;
int trade_i;
nullpo_retv(sd);
-
- for(trade_i=0;trade_i<10;trade_i++) {
- if(sd->deal_item_amount[trade_i]>sd->status.inventory[sd->deal_item_index[trade_i]-2].amount ||
- sd->deal_item_amount[trade_i]<0) {
+
+ // check items
+ for(trade_i = 0; trade_i < 10; trade_i++) {
+ if ((((sd->deal_item_index[trade_i]-2) >= 0) &&
+ (sd->deal_item_amount[trade_i] > sd->status.inventory[sd->deal_item_index[trade_i]-2].amount)) ||
+ (sd->deal_item_amount[trade_i] < 0)) {
trade_tradecancel(sd);
return;
}
-
}
-
- if((target_sd = map_id2sd(sd->trade_partner)) != NULL){
- sd->deal_locked=1;
- clif_tradeitemok(sd,0,0);
- clif_tradedeal_lock(sd,0);
- clif_tradedeal_lock(target_sd,1);
+
+ // check exploit (trade more items that you have)
+ if (impossible_trade_check(sd)) {
+ trade_tradecancel(sd);
+ return;
+ }
+
+ // check zeny
+ if (sd->deal_zeny < 0 || sd->deal_zeny > MAX_ZENY || sd->deal_zeny > sd->status.zeny) { // check amount
+ trade_tradecancel(sd);
+ return;
+ }
+
+ if ((target_sd = map_id2sd(sd->trade_partner)) != NULL) {
+ sd->deal_locked = 1;
+ clif_tradeitemok(sd, 0, 0);
+ clif_tradedeal_lock(sd, 0);
+ clif_tradedeal_lock(target_sd, 1);
}
}
@@ -162,38 +253,37 @@ void trade_tradeok(struct map_session_data *sd)
* ŽæˆøƒLƒƒƒ“ƒZƒ‹
*------------------------------------------
*/
-void trade_tradecancel(struct map_session_data *sd)
-{
+void trade_tradecancel(struct map_session_data *sd) {
struct map_session_data *target_sd;
int trade_i;
nullpo_retv(sd);
- if((target_sd = map_id2sd(sd->trade_partner)) != NULL){
- for(trade_i=0; trade_i<10;trade_i++) { //give items back (only virtual)
- if(sd->deal_item_amount[trade_i] != 0) {
- clif_additem(sd,sd->deal_item_index[trade_i]-2,sd->deal_item_amount[trade_i],0);
- sd->deal_item_index[trade_i] =0;
- sd->deal_item_amount[trade_i]=0;
+ if ((target_sd = map_id2sd(sd->trade_partner)) != NULL) {
+ for(trade_i = 0; trade_i < 10; trade_i++) { // give items back (only virtual)
+ if (sd->deal_item_amount[trade_i] != 0) {
+ clif_additem(sd, sd->deal_item_index[trade_i] - 2, sd->deal_item_amount[trade_i], 0);
+ sd->deal_item_index[trade_i] = 0;
+ sd->deal_item_amount[trade_i] = 0;
}
- if(target_sd->deal_item_amount[trade_i] != 0) {
- clif_additem(target_sd,target_sd->deal_item_index[trade_i]-2,target_sd->deal_item_amount[trade_i],0);
- target_sd->deal_item_index[trade_i] =0;
- target_sd->deal_item_amount[trade_i]=0;
+ if (target_sd->deal_item_amount[trade_i] != 0) {
+ clif_additem(target_sd, target_sd->deal_item_index[trade_i] - 2, target_sd->deal_item_amount[trade_i], 0);
+ target_sd->deal_item_index[trade_i] = 0;
+ target_sd->deal_item_amount[trade_i] = 0;
}
}
- if(sd->deal_zeny) {
- clif_updatestatus(sd,SP_ZENY);
- sd->deal_zeny=0;
+ if (sd->deal_zeny) {
+ clif_updatestatus(sd, SP_ZENY);
+ sd->deal_zeny = 0;
}
- if(target_sd->deal_zeny) {
- clif_updatestatus(target_sd,SP_ZENY);
- target_sd->deal_zeny=0;
+ if (target_sd->deal_zeny) {
+ clif_updatestatus(target_sd, SP_ZENY);
+ target_sd->deal_zeny = 0;
}
- sd->deal_locked =0;
- sd->trade_partner=0;
- target_sd->deal_locked=0;
- target_sd->trade_partner=0;
+ sd->deal_locked = 0;
+ sd->trade_partner = 0;
+ target_sd->deal_locked = 0;
+ target_sd->trade_partner = 0;
clif_tradecancelled(sd);
clif_tradecancelled(target_sd);
}
@@ -203,91 +293,96 @@ void trade_tradecancel(struct map_session_data *sd)
* Žæˆø‹–‘ø(trade‰Ÿ‚µ)
*------------------------------------------
*/
-void trade_tradecommit(struct map_session_data *sd)
-{
+void trade_tradecommit(struct map_session_data *sd) {
struct map_session_data *target_sd;
int trade_i;
+ int flag;
nullpo_retv(sd);
- if((target_sd = map_id2sd(sd->trade_partner)) != NULL){
- if( (sd->deal_locked >=1) && (target_sd->deal_locked >=1) ){ // both have pressed 'ok'
- if(sd->deal_locked < 2) {sd->deal_locked=2;} // set locked to 2
- if(target_sd->deal_locked==2) { // the other one pressed 'trade' too
- for(trade_i=0; trade_i<10;trade_i++) {
- if(sd->deal_item_amount[trade_i] != 0) {
- int n=sd->deal_item_index[trade_i]-2;
- int flag;
-
- //Dupe Fix by mark
- if (sd->status.inventory[n].amount < sd->deal_item_amount[trade_i])
- sd->deal_item_amount[trade_i] = sd->status.inventory[n].amount;
- //End Dupe Fix
-
- #ifndef TXT_ONLY
- if(log_config.trade > 0)
- log_trade(sd,target_sd,n,sd->deal_item_amount[trade_i]);
- #endif //USE_SQL
-
- flag = pc_additem(target_sd,&sd->status.inventory[n],sd->deal_item_amount[trade_i]);
- if(flag==0)
- pc_delitem(sd,n,sd->deal_item_amount[trade_i],1);
- else
- clif_additem(sd,n,sd->deal_item_amount[trade_i],0);
- sd->deal_item_index[trade_i] =0;
- sd->deal_item_amount[trade_i]=0;
- }
- if(target_sd->deal_item_amount[trade_i] != 0) {
- int n=target_sd->deal_item_index[trade_i]-2;
- int flag;
-
- //Dupe Fix by mark
- if (target_sd->status.inventory[n].amount < target_sd->deal_item_amount[trade_i])
- target_sd->deal_item_amount[trade_i] = target_sd->status.inventory[n].amount;
- //End Dupe Fix
-
- #ifndef TXT_ONLY
- if(log_config.trade > 0)
- log_trade(target_sd,sd,n,target_sd->deal_item_amount[trade_i]);
- #endif //USE_SQL
-
- flag = pc_additem(sd,&target_sd->status.inventory[n],target_sd->deal_item_amount[trade_i]);
- if(flag==0)
- pc_delitem(target_sd,n,target_sd->deal_item_amount[trade_i],1);
- else
- clif_additem(target_sd,n,target_sd->deal_item_amount[trade_i],0);
- target_sd->deal_item_index[trade_i] =0;
- target_sd->deal_item_amount[trade_i]=0;
- }
+ if ((target_sd = map_id2sd(sd->trade_partner)) != NULL) {
+ if ((sd->deal_locked >= 1) && (target_sd->deal_locked >= 1)) { // both have pressed 'ok'
+ if (sd->deal_locked < 2) { // set locked to 2
+ sd->deal_locked = 2;
+ }
+ if (target_sd->deal_locked == 2) { // the other one pressed 'trade' too
+ // check exploit (trade more items that you have)
+ if (impossible_trade_check(sd)) {
+ trade_tradecancel(sd);
+ return;
}
- if(sd->deal_zeny) {
- #ifndef TXT_ONLY
- if (log_config.trade > 0 && log_config.zeny > 0)
- log_zeny(sd, target_sd, sd->deal_zeny);
- #endif //USE_SQL
- sd->status.zeny -= sd->deal_zeny;
- clif_updatestatus(sd,SP_ZENY);
- target_sd->status.zeny += sd->deal_zeny;
- clif_updatestatus(target_sd,SP_ZENY);
- sd->deal_zeny=0;
+ // check exploit (trade more items that you have)
+ if (impossible_trade_check(target_sd)) {
+ trade_tradecancel(target_sd);
+ return;
}
- if(target_sd->deal_zeny) {
- #ifndef TXT_ONLY
- if (log_config.trade > 0 && log_config.zeny > 0)
- log_zeny(target_sd, sd, target_sd->deal_zeny);
- #endif //USE_SQL
- target_sd->status.zeny -= target_sd->deal_zeny;
- clif_updatestatus(target_sd,SP_ZENY);
- sd->status.zeny += target_sd->deal_zeny;
- clif_updatestatus(sd,SP_ZENY);
- target_sd->deal_zeny=0;
+ // check zenys value against hackers
+ if (sd->deal_zeny >= 0 && sd->deal_zeny <= MAX_ZENY && sd->deal_zeny <= sd->status.zeny && // check amount
+ (target_sd->status.zeny + sd->deal_zeny) <= MAX_ZENY && // fix positiv overflow
+ target_sd->deal_zeny >= 0 && target_sd->deal_zeny <= MAX_ZENY && target_sd->deal_zeny <= target_sd->status.zeny && // check amount
+ (sd->status.zeny + target_sd->deal_zeny) <= MAX_ZENY) { // fix positiv overflow
+
+ // trade is accepted
+ for(trade_i = 0; trade_i < 10; trade_i++) {
+ if (sd->deal_item_amount[trade_i] != 0) {
+ int n = sd->deal_item_index[trade_i] - 2;
+
+ if (sd->status.inventory[n].amount < sd->deal_item_amount[trade_i])
+ sd->deal_item_amount[trade_i] = sd->status.inventory[n].amount;
+ log_trade(sd, target_sd, n, sd->deal_item_amount[trade_i]);
+
+ flag = pc_additem(target_sd, &sd->status.inventory[n], sd->deal_item_amount[trade_i]);
+ if (flag == 0)
+ pc_delitem(sd, n, sd->deal_item_amount[trade_i], 1);
+ else
+ clif_additem(sd, n, sd->deal_item_amount[trade_i], 0);
+ sd->deal_item_index[trade_i] = 0;
+ sd->deal_item_amount[trade_i] = 0;
+
+ }
+ if (target_sd->deal_item_amount[trade_i] != 0) {
+ int n = target_sd->deal_item_index[trade_i] - 2;
+
+ if (target_sd->status.inventory[n].amount < target_sd->deal_item_amount[trade_i])
+ target_sd->deal_item_amount[trade_i] = target_sd->status.inventory[n].amount;
+
+ log_trade(target_sd, sd, n, target_sd->deal_item_amount[trade_i]);
+ flag = pc_additem(sd, &target_sd->status.inventory[n], target_sd->deal_item_amount[trade_i]);
+ if (flag == 0)
+ pc_delitem(target_sd, n, target_sd->deal_item_amount[trade_i], 1);
+ else
+ clif_additem(target_sd, n, target_sd->deal_item_amount[trade_i], 0);
+ target_sd->deal_item_index[trade_i] = 0;
+ target_sd->deal_item_amount[trade_i] = 0;
+ }
+ }
+ if (sd->deal_zeny) {
+ sd->status.zeny -= sd->deal_zeny;
+ target_sd->status.zeny += sd->deal_zeny;
+ }
+ if (target_sd->deal_zeny) {
+ target_sd->status.zeny -= target_sd->deal_zeny;
+ sd->status.zeny += target_sd->deal_zeny;
+ }
+ if (sd->deal_zeny || target_sd->deal_zeny) {
+ clif_updatestatus(sd, SP_ZENY);
+ sd->deal_zeny = 0;
+ clif_updatestatus(target_sd, SP_ZENY);
+ target_sd->deal_zeny = 0;
+ }
+ sd->deal_locked = 0;
+ sd->trade_partner = 0;
+ target_sd->deal_locked = 0;
+ target_sd->trade_partner = 0;
+ clif_tradecompleted(sd, 0);
+ clif_tradecompleted(target_sd, 0);
+ // save both player to avoid crash: they always have no advantage/disadvantage between the 2 players
+ chrif_save(sd); // do pc_makesavestatus and save storage too
+ chrif_save(target_sd); // do pc_makesavestatus and save storage too
+ // zeny value was modified!!!! hacker with packet modified
+ } else {
+ trade_tradecancel(sd);
}
- sd->deal_locked =0;
- sd->trade_partner=0;
- target_sd->deal_locked=0;
- target_sd->trade_partner=0;
- clif_tradecompleted(sd,0);
- clif_tradecompleted(target_sd,0);
}
}
}
diff --git a/src/map/vending.c b/src/map/vending.c
index a7aa708e5..2d3790596 100644
--- a/src/map/vending.c
+++ b/src/map/vending.c
@@ -48,7 +48,7 @@ void vending_vendinglistreq(struct map_session_data *sd,int id)
*/
void vending_purchasereq(struct map_session_data *sd,int len,int id,unsigned char *p)
{
- int i, j, w, z, new = 0, blank, vend_list[12];
+ int i, j, w, z, new_ = 0, blank, vend_list[12];
short amount, index;
struct map_session_data *vsd = map_id2sd(id);
@@ -99,8 +99,8 @@ void vending_purchasereq(struct map_session_data *sd,int len,int id,unsigned cha
case ADDITEM_EXIST:
break;
case ADDITEM_NEW:
- new++;
- if (new > blank)
+ new_++;
+ if (new_ > blank)
return; // Ží—Þ”’´‰ß
break;
case ADDITEM_OVERAMOUNT:
@@ -112,6 +112,7 @@ void vending_purchasereq(struct map_session_data *sd,int len,int id,unsigned cha
clif_tradecancelled(vsd);
return;
}
+
pc_payzeny(sd, z);
pc_getzeny(vsd, z);
for(i = 0; 8 + 4 * i < len; i++) {
@@ -122,6 +123,13 @@ void vending_purchasereq(struct map_session_data *sd,int len,int id,unsigned cha
vsd->vending[vend_list[i]].amount -= amount;
pc_cart_delitem(vsd, index, amount, 0);
clif_vendingreport(vsd, index, amount);
+
+ //log added by Lupus
+ if(log_config.vend > 0) {
+ log_vend(sd,vsd, index, amount, z); // for Item + Zeny. log.
+ //we log ZENY only with the 1st item. Then zero it for the rest items 8).
+ z = 0;
+ }
}
}
@@ -141,11 +149,14 @@ void vending_openvending(struct map_session_data *sd,int len,char *message,int f
}
if (flag) {
- for(i = 0; 85 + 8 * i < len; i++) {
+ for(i = 0; (85 + 8 * i < len) && (i < MAX_VENDING); i++) {
sd->vending[i].index = *(short*)(p+8*i)-2;
sd->vending[i].amount = *(short*)(p+2+8*i);
sd->vending[i].value = *(int*)(p+4+8*i);
- if(sd->vending[i].value>battle_config.vending_max_value)sd->vending[i].value=battle_config.vending_max_value;
+ if(sd->vending[i].value > battle_config.vending_max_value)
+ sd->vending[i].value=battle_config.vending_max_value;
+ else if(sd->vending[i].value == 0)
+ sd->vending[i].value = 1000000; // auto set to 1 million [celest]
// ƒJ[ƒg“à‚̃AƒCƒeƒ€”‚Ɣ̔„‚·‚éƒAƒCƒeƒ€”‚É‘Šˆá‚ª‚ ‚Á‚½‚ç’†Ž~
if(pc_cartitem_amount(sd, sd->vending[i].index, sd->vending[i].amount) < 0 || sd->vending[i].value < 0) { // fixes by Valaris and fritz
clif_skill_fail(sd, MC_VENDING, 0, 0);
diff --git a/src/tool/Makefile b/src/tool/Makefile
new file mode 100644
index 000000000..bbf18cf98
--- /dev/null
+++ b/src/tool/Makefile
@@ -0,0 +1,6 @@
+all:
+ $(CC) -o adduser adduser.c
+
+clean:
+ rm -f adduser
+ rm -f *.exe
diff --git a/src/tool/adduser.c b/src/tool/adduser.c
new file mode 100644
index 000000000..1219540ab
--- /dev/null
+++ b/src/tool/adduser.c
@@ -0,0 +1,96 @@
+/*
+ This program adds an user to account.txt
+ Don't usr it When login-sever is working.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char *account_txt = "../save/account.txt";
+
+//-----------------------------------------------------
+// Function to suppress control characters in a string.
+//-----------------------------------------------------
+int remove_control_chars(unsigned char *str) {
+ int i;
+ int change = 0;
+
+ for(i = 0; str[i]; i++) {
+ if (str[i] < 32) {
+ str[i] = '_';
+ change = 1;
+ }
+ }
+
+ return change;
+}
+
+int main(int argc, char *argv[]) {
+
+ char username[24];
+ char password[24];
+ char sex[2];
+
+ int next_id, id;
+ char line[1024];
+
+ // Check to see if account.txt exists.
+ printf("Checking if '%s' file exists...\n", account_txt);
+ FILE *FPaccin = fopen(account_txt, "r");
+ if (FPaccin == NULL) {
+ printf("'%s' file not found!\n", account_txt);
+ printf("Run the setup wizard please.\n");
+ exit(0);
+ }
+
+ next_id = 2000000;
+ while(fgets(line, sizeof(line)-1, FPaccin)) {
+ if (line[0] == '/' && line[1] == '/') { continue; }
+ if (sscanf(line, "%d\t%%newid%%\n", &id) == 1) {
+ if (next_id < id) {
+ next_id = id;
+ }
+ } else {
+ sscanf(line,"%i%[^ ]", &id);
+ if (next_id <= id) {
+ next_id = id +1;
+ }
+ }
+ }
+ close(FPaccin);
+ printf("File exists.\n");
+
+ printf("Don't create an account if the login-server is online!!!\n");
+ printf("If the login-server is online, press ctrl+C now to stop this software.\n");
+ printf("\n");
+
+ strcpy(username, "");
+ while (strlen(username) < 4 || strlen(username) > 23) {
+ printf("Enter an username (4-23 characters): ");
+ scanf("%s", &username);
+ username[23] = 0;
+ remove_control_chars(username);
+ }
+
+ strcpy(password, "");
+ while (strlen(password) < 4 || strlen(password) > 23) {
+ printf("Enter a password (4-23 characters): ");
+ scanf("%s", &password);
+ password[23] = 0;
+ remove_control_chars(password);
+ }
+
+ strcpy(sex, "");
+ while (strcmp(sex, "F") != 0 && strcmp(sex, "M") != 0) {
+ printf("Enter a gender (M for male, F for female): ");
+ scanf("%s", &sex);
+ }
+
+ FILE *FPaccout = fopen(account_txt, "r+");
+ fseek(FPaccout, 0, SEEK_END);
+ fprintf(FPaccout, "%i %s %s - %s -\r\n", next_id, username, password, sex);
+ close(FPaccout);
+
+ printf("Account added.\n");
+}
diff --git a/src/tool/backup b/src/tool/backup
new file mode 100644
index 000000000..939c7eee7
--- /dev/null
+++ b/src/tool/backup
@@ -0,0 +1,100 @@
+#!/usr/bin/perl
+
+##########################################################################
+# Athena—pƒf[ƒ^ƒoƒbƒNƒAƒbƒvƒc[ƒ‹
+#
+# @Athena‚ÌŠeŽíƒf[ƒ^ƒtƒ@ƒCƒ‹*.txt‚ðƒoƒbƒNƒAƒbƒv‚·‚éƒc[ƒ‹
+#
+#-------------------------------------------------------------------------
+# Ý’è•û–@
+# @ŽÀs‚·‚鎞‚̃JƒŒƒ“ƒgƒtƒHƒ‹ƒ_‚©‚ç‚̃f[ƒ^‚ւ̃pƒXAƒtƒ@ƒCƒ‹‚ÌƒŠƒXƒg‚ð
+# @³‚µ‚­Ý’肵‚Ü‚·BƒoƒbƒNƒAƒbƒvæ‚̃tƒHƒ‹ƒ_‚ÍŽ©“®ì¬‚³‚ê‚È‚¢‚Ì‚ÅA
+# @Ž©•ª‚Å쬂µ‚Ä‚¨‚­•K—v‚ª‚ ‚è‚Ü‚·B
+# @ƒtƒHƒ‹ƒ_‚ÌÅŒã‚Ìu/v‚ÍÈ—ª‚Å‚«‚Ü‚¹‚ñB
+#
+# @ƒtƒHƒ‹ƒ_‚͈ø”‚Å‚àŽw’è‚Å‚«‚Ü‚·B—á„./backup ../save/ ./backup_data/
+# @ƒtƒHƒ‹ƒ_‚ÌÅŒã‚Ìu/v‚ÍÈ—ª‚Å‚«‚Ü‚¹‚ñB
+#
+# @ŽÀs‚·‚邯ƒoƒbƒNƒAƒbƒvæ‚̃tƒHƒ‹ƒ_‚ÖAƒtƒ@ƒCƒ‹–¼‚ÉŒ»Ý‚Ì“ú•t‚ÆŽž‚ð
+# @‚‚¯‚ătƒ@ƒCƒ‹‚ðƒRƒs[‚µ‚Ü‚·B
+#
+# * toolƒtƒHƒ‹ƒ_“à‚Ébackup_dataƒtƒHƒ‹ƒ_‚ð쬂µA
+# @ athena.sh‚Ì’†‚Éu./tool/backup ./save/ ./tool/backup_data/v
+# ‚Æ‚¢‚¤s‚ð’ljÁ‚·‚邯Aathena‚ð‹N“®‚·‚邽‚тɃoƒbƒNƒAƒbƒv‚ªŽæ‚ê‚Ü‚·
+#
+# •œŒ³‚·‚邯‚«‚͈ø”‚Éu-r “ú•t‚ÆŽžv‚ðŽw’肵‚Ü‚·B
+# @‚Ü‚½‚»‚ÌŒã‚ë‚ɃtƒHƒ‹ƒ_‚ðŽw’è‚·‚邱‚Æ‚ào—ˆ‚Ü‚·
+# @—á‚P„ ./backup -r 200309191607
+# @—á‚Q„ ./backup -r 200309191607 ../save ./backup_data/
+# @‚±‚Ì—á‚Å‚Í2003/09/19‚Ì16:07•ª‚ɃoƒbƒNƒAƒbƒv‚µ‚½ƒf[ƒ^‚𕜌³‚µ‚Ä‚¢‚Ü‚·
+#
+# @•œŒ³‚·‚邯‚«AAthenaƒfƒBƒŒƒNƒgƒŠ‚É‚ ‚éƒf[ƒ^‚Í *.bak ‚É–¼‘O‚ð•ÏX‚µ‚Ä
+# @Žc‚µ‚Ä‚¢‚é‚Ì‚ÅA‚¢‚ç‚È‚¢ê‡‚Í rm *.bak ‚ȂǂÅÁ‚µ‚Ä‚­‚¾‚³‚¢B
+#
+##########################################################################
+
+$sdir="../save/"; #ƒoƒbƒNƒAƒbƒvŒ³(Athena‚̃fƒBƒŒƒNƒgƒŠ/save/)
+$tdir="./backup_data/"; #ƒoƒbƒNƒAƒbƒvæ
+
+@files=( #ƒtƒ@ƒCƒ‹‚ÌƒŠƒXƒg
+ "account","athena","storage","party","guild","castle","pet"
+);
+
+
+#-------------------------------ݒ肱‚±‚Ü‚Å-----------------------------
+
+
+
+
+
+
+
+
+
+
+
+if($ARGV[0]=~/^\-r$/i || $ARGV[0]=~/\-\-(recover|restore)/i){
+ #•œŒ³ˆ—
+
+ $file=$ARGV[1];
+ $sdir=$ARGV[2]||$sdir;
+ $tdir=$ARGV[3]||$tdir;
+ &restorecopy($_) foreach @files;
+ exit(0);
+}
+
+#ƒoƒbƒNƒAƒbƒvˆ—
+$sdir=$ARGV[0]||$sdir;
+$tdir=$ARGV[1]||$tdir;
+
+unless( -d $tdir ){
+ print "$0: \"$tdir\" : No such directory\n";
+ exit(1);
+}
+
+(undef,$min,$hour,$day,$month,$year)=localtime;
+
+$file=sprintf("%04d%02d%02d%02d%02d",
+ $year+1900, $month+1, $day, $hour, $min );
+
+&backupcopy($_) foreach @files;
+exit(0);
+
+sub backupcopy {
+ my($name)= @_;
+ system("cp $sdir$name.txt $tdir$name$file.txt");
+}
+
+sub restorecopy {
+ my($name)= @_;
+ unless( -f "$sdir$name.txt" ){
+ printf("$0: \"$sdir$name.txt\" not found!\n");
+ return 0;
+ }
+ unless( -f "$tdir$name$file.txt" ){
+ printf("$0: \"$tdir$name$file.txt\" not found!\n");
+ return 0;
+ }
+ rename "$sdir$name.txt","$sdir$name.bak";
+ system("cp $tdir$name$file.txt $sdir$name.txt");
+}
diff --git a/src/tool/cgi/addaccount.cgi b/src/tool/cgi/addaccount.cgi
new file mode 100644
index 000000000..7d1788c48
--- /dev/null
+++ b/src/tool/cgi/addaccount.cgi
@@ -0,0 +1,204 @@
+#!/usr/bin/perl
+
+#=========================================================================
+# addaccount.cgi ver.1.00
+# ladmin‚ðƒ‰ƒbƒv‚µ‚½AƒAƒJƒEƒ“ƒg‚ð쬂·‚éCGIB
+# ladmin ver.1.04‚ł̓®ì‚ðŠm”FB
+#
+# ** Ý’è•û–@ **
+#
+# - ‰º‚Ì$ladmin•Ï”‚Éladmin‚ւ̃pƒX‚ðÝ’è‚·‚邱‚ÆB
+# - UNIXŒnOS‚ÅŽg—p‚·‚éꇂÍladmin‚Æ‹¤‚ɉüsƒR[ƒh‚ð•ÏŠ·‚·‚邱‚ÆA‚Ü‚½
+# ƒtƒ@ƒCƒ‹æ“ªs‚ðperl‚̳‚µ‚¢ƒpƒX‚É‚·‚邱‚ÆB—á> $ which perl
+# - ƒT[ƒo[ƒvƒƒOƒ‰ƒ€‚âƒuƒ‰ƒEƒU‚É‚æ‚Á‚Ä‚Í $cgiuri ‚É‚±‚̃tƒ@ƒCƒ‹‚Ö‚Ì
+# Š®‘S‚ÈURI‚ðƒZƒbƒg‚µ‚È‚¯‚ê‚΂Ȃç‚È‚¢ê‡‚à‚ ‚éB
+# - perl‚ɃpƒX‚ª’Ê‚Á‚Ä‚¢‚È‚¢ê‡‚Í $perl ‚ðperl‚ւ̳‚µ‚¢ƒpƒX‚É‚·‚邱‚ÆB
+# - ‘¼‚Í•’Ê‚ÌCGI‚Æ“¯‚¶‚Å‚·BiŽÀsŒ ‚âcgi-binƒtƒHƒ‹ƒ_‚È‚Çj
+#
+# ** ‚»‚Ì‘¼ **
+# addaccount.cgi ‚ðƒuƒ‰ƒEƒU‚ÅŠJ‚­‚ƃTƒ“ƒvƒ‹HTMLi‚»‚̂܂܎g‚¦‚Ü‚·j‚ª
+# ŠJ‚«‚Ü‚·B‚Ü‚½A‚±‚Ìcgi‚̓uƒ‰ƒEƒU‚©‚ç‘—‚ç‚ê‚éAccept-Language‚ª
+# ja‚ÅŽn‚Ü‚Á‚Ä‚¢‚ê‚΃ƒbƒZ[ƒW‚̈ꕔ‚ð“ú–{Œê‚ɕϊ·‚µ‚Ü‚·B
+# (IE‚È‚çƒCƒ“ƒ^[ƒlƒbƒgƒIƒvƒVƒ‡ƒ“‚ÌŒ¾ŒêÝ’è‚ňê”Ôã‚É“ú–{Œê‚ð’u‚­)
+# ‚»‚êˆÈŠO‚Ìꇂ͉pŒê‚̂܂Üo—Í‚µ‚Ü‚·B
+#-------------------------------------------------------------------------
+
+my($ladmin) = "../ladmin"; # ladmin‚̃pƒX(‚¨‚»‚ç‚­•ÏX‚ª•K—v)
+
+my($cgiuri) = "./addaccount.cgi"; # ‚±‚̃tƒ@ƒCƒ‹‚ÌURI
+my($perl) = "perl"; # perl‚̃Rƒ}ƒ“ƒh–¼
+
+
+
+#--------------------------- ݒ肱‚±‚܂Š--------------------------------
+
+
+
+
+
+
+use strict;
+use CGI;
+
+my($cgi)= new CGI;
+my(%langconv)=(
+ 'Athena login-server administration tool.*' => '',
+ 'logged on.*' => '',
+);
+
+# ----- “ú–{ŒêŠÂ‹«‚È‚ç•ÏŠ·ƒe[ƒuƒ‹‚ðƒZƒbƒg -----
+if($ENV{'HTTP_ACCEPT_LANGUAGE'}=~/^ja/){
+ my(%tmp)=(
+ 'Account \[(.+)\] is successfully created.*'
+ => 'ƒAƒJƒEƒ“ƒg "$1" ‚ð쬂µ‚Ü‚µ‚½.',
+ 'Account \[(.+)\] creation failed\. same account exists.*'
+ => 'ƒAƒJƒEƒ“ƒg "$1" ‚ÍŠù‚É‘¶Ý‚µ‚Ü‚·.',
+ 'Illeagal charactor found in UserID.*'
+ => 'ID‚Ì’†‚É•s³‚È•¶Žš‚ª‚ ‚è‚Ü‚·.',
+ 'Illeagal charactor found in Password.*'
+ => 'Password‚Ì’†‚É•s³‚È•¶Žš‚ª‚ ‚è‚Ü‚·.',
+ 'input UserID 4-24 bytes.'
+ => 'ID‚Í”¼Šp4`24•¶Žš‚Å“ü—Í‚µ‚Ä‚­‚¾‚³‚¢.',
+ 'input Password 4-24 bytes.'
+ => 'Password‚Í”¼Šp4`24•¶Žš‚Å“ü—Í‚µ‚Ä‚­‚¾‚³‚¢.',
+ 'Illeagal gender.*'
+ => '«•Ê‚ª‚¨‚©‚µ‚¢‚Å‚·.',
+ 'Cant connect to login server.*'
+ => 'ƒƒOƒCƒ“ƒT[ƒo[‚ÉÚ‘±‚Å‚«‚Ü‚¹‚ñ.',
+ 'login error.*'
+ => 'ƒƒOƒCƒ“ƒT[ƒo[‚Ö‚ÌŠÇ—ŽÒŒ ŒÀƒƒOƒCƒ“‚ÉŽ¸”s‚µ‚Ü‚µ‚½',
+ "Can't execute ladmin.*"
+ => 'ladmin‚ÌŽÀs‚ÉŽ¸”s‚µ‚Ü‚µ‚½',
+ 'UserID "(.+)" is already used.*'
+ => 'ID "$1" ‚ÍŠù‚ÉŽg—p‚³‚ê‚Ä‚¢‚Ü‚·.',
+ 'You can use UserID \"(.+)\".*'
+ => 'ID "$1" ‚ÍŽg—p‰Â”\‚Å‚·.',
+
+ 'account making' =>'ƒAƒJƒEƒ“ƒgì¬',
+ '\>UserID' =>'>‚h‚c',
+ '\>Password' =>'>ƒpƒXƒ[ƒh',
+ '\>Gender' =>'>«•Ê',
+ '\>Male' =>'>’j«',
+ '\>Female' =>'>—«',
+ '\"Make Account\"' =>'"ƒAƒJƒEƒ“ƒgì¬"',
+ '\"Check UserID\"' =>'"ID‚̃`ƒFƒbƒN"',
+ );
+ map { $langconv{$_}=$tmp{$_}; } keys (%tmp);
+}
+
+# ----- ’ljÁ -----
+if( $cgi->param("addaccount") ){
+ my($userid)= $cgi->param("userid");
+ my($passwd)= $cgi->param("passwd");
+ my($gender)= lc(substr($cgi->param("gender"),0,1));
+ if(length($userid)<4 || length($userid)>24){
+ HttpError("input UserID 4-24 bytes.");
+ }
+ if(length($passwd)<4 || length($passwd)>24){
+ HttpError("input Password 4-24 bytes.");
+ }
+ if($userid=~/[^0-9A-Za-z\@\_\-\']/){
+ HttpError("Illeagal charactor found in UserID.");
+ }
+ if($passwd=~/[\x00-\x1f\x80-\xff\']/){
+ HttpError("Illeagal charactor found in Password.");
+ }
+ if($gender!~/[mf]/){
+ HttpError("Gender error.");
+ }
+ open PIPE,"$perl $ladmin --add $userid $gender $passwd |"
+ or HttpError("Can't execute ladmin.");
+ my(@msg)=<PIPE>;
+ close PIPE;
+ HttpMsg(@msg);
+}
+# ----- ‘¶Ýƒ`ƒFƒbƒN -----
+elsif( $cgi->param("check") ){
+ my($userid)= $cgi->param("userid");
+ if(length($userid)<4 || length($userid)>24){
+ HttpError("input UserID 4-24 bytes.");
+ }
+ if($userid=~/[^0-9A-Za-z\@\_\-\']/){
+ HttpError("Illeagal charactor found in UserID.");
+ }
+ open PIPE,"$perl $ladmin --search --regex \\b$userid\\b |"
+ or HttpError("Can't execute ladmin.");
+ my(@msg)=<PIPE>;
+ close PIPE;
+ if(scalar(@msg)==6 && (split /[\s\0]+/,substr($msg[4],11,24))[0] eq $userid){
+ HttpMsg("NG : UserID \"$userid\" is already used.");
+ }elsif(scalar(@msg)==5){
+ HttpMsg("OK : You can use UserID \"$userid\"");
+ }
+ HttpError("ladmin error ?\n---output---\n",@msg);
+}
+
+# ----- ƒtƒH[ƒ€ -----
+else{
+ print LangConv( <<"EOM" );
+Content-type: text/html\n
+<html>
+ <head>
+ <title>Athena account making cgi</title>
+ </head>
+ <body>
+ <h1>Athena account making cgi</h1>
+ <form action="$cgiuri" method="post">
+ <table border=2>
+ <tr>
+ <th>UserID</th>
+ <td><input name="userid" size=24 maxlength=24></td>
+ </tr>
+ <tr>
+ <th>Password</th>
+ <td><input name="passwd" size=24 maxlength=24 type="password"></td>
+ </tr>
+ <tr>
+ <th>Gender</th>
+ <td>
+ <input type="radio" name="gender" value="male">Male
+ <input type="radio" name="gender" value="female">Female
+ </td>
+ </tr>
+ <tr>
+ <td colspan=2>
+ <input type="submit" name="addaccount" value="Make Account">
+ <input type="submit" name="check" value="Check UserID">
+ </td>
+ </tr>
+ </table>
+ </form>
+ </body>
+</html>
+EOM
+ exit;
+}
+
+sub LangConv {
+ my(@lst)= @_;
+ my($a,$b,@out)=();
+ foreach $a(@lst){
+ foreach $b(keys %langconv){
+ $a=~s/$b/$langconv{$b}/g;
+ my($rep1)=$1;
+ $a=~s/\$1/$rep1/g;
+ }
+ push @out,$a;
+ }
+ return @out;
+}
+
+sub HttpMsg {
+ my($msg)=join("", LangConv(@_));
+ $msg=~s/\n/<br>\n/g;
+ print LangConv("Content-type: text/html\n\n"),$msg;
+ exit;
+}
+
+sub HttpError {
+ my($msg)=join("", LangConv(@_));
+ $msg=~s/\n/<br>\n/g;
+ print LangConv("Content-type: text/html\n\n"),$msg;
+ exit;
+}
+
diff --git a/src/tool/checkversion b/src/tool/checkversion
new file mode 100644
index 000000000..9e485d9a3
--- /dev/null
+++ b/src/tool/checkversion
@@ -0,0 +1,85 @@
+#!/usr/bin/perl -w
+
+##########################################################################
+# INFORMATION TOOL ABOUT THE SERVERS VERSION OF ATHENA
+#
+# By connection on a server, this software display the version of the
+# designed server.
+#-------------------------------------------------------------------------
+# Usages:
+# ./checkversion IP:port
+# ./checkversion IP port
+# perl checkversion IP:port
+# perl checkversion IP port
+#
+# note: default port: 6900
+#
+# When successfull, the software return the value 0.
+#
+##########################################################################
+
+#------------------------- start of configuration ------------------------
+
+$connecttimeout = 10; # Connection Timeout (in seconds)
+
+#-------------------------- End of configuration -------------------------
+
+use IO::Socket;
+
+unless($ARGV[0]) {
+ print "USAGE: $0 server_ip:port\n";
+ exit(1);
+}
+
+$server = $ARGV[0];
+$port = $ARGV[1];
+$port = $1 if ($server =~ s/:(\d+)//);
+$port ||= 6900;
+
+# Connection to the server
+my($so,$er) = ();
+eval{
+ $so = IO::Socket::INET->new(
+ PeerAddr=> $server,
+ PeerPort=> $port,
+ Proto => "tcp",
+ Timeout => $connecttimeout) or $er = 1;
+};
+
+if($er || $@) {
+ print "Can't not connect to server [$server:$port] !\n";
+ exit(2);
+}
+
+# Request for the server version
+print $so pack("v",30000); # 0x7530
+$so->flush();
+
+# Receiving of the answer of the server
+if (read($so,$buf,10) < 10) {
+ print "Invalid answer. It isn't an athena server or it is a too old version.\n";
+ exit(5);
+}
+
+# Sending end of connection to the server
+print $so pack("v",30002); # 0x7532
+$so->flush();
+
+# Analyse of the answer
+my($ret,$maver,$miver,$rev,$dev,$mod,$type,$mdver) = unpack("v c6 v",$buf);
+
+if ($ret != 30001) { # 0x7531
+ print "Invalid answer. It isn't an athena server or it is a too old version.\n";
+ exit(6);
+}
+
+my(@stype) = ();
+foreach $i(0..3) {
+ push @stype,(("login","char","inter","map")[$i]) if( $type & (1<<$i) );
+}
+print " ".join("/",@stype)." server [$server:$port].\n";
+printf " Athena version %s-%d.%d", ("stable","dev")[$dev], $maver,$miver;
+printf " revision %d",$rev if $rev;
+printf "%s%d\n",("","-mod")[$mod],$mdver;
+
+exit(0);
diff --git a/src/tool/convert.c b/src/tool/convert.c
new file mode 100644
index 000000000..16631c945
--- /dev/null
+++ b/src/tool/convert.c
@@ -0,0 +1,296 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define RETCODE "\r\n"
+
+#define MAX_INVENTORY 100
+#define MAX_CART 100
+#define MAX_SKILL 350
+#define GLOBAL_REG_NUM 16
+
+struct item {
+ int id;
+ short nameid;
+ short amount;
+ short equip;
+ char identify;
+ char refine;
+ char attribute;
+ short card[4];
+};
+struct point{
+ char map[16];
+ short x,y;
+};
+struct skill {
+ unsigned short id,lv,flag;
+};
+struct global_reg {
+ char str[16];
+ int value;
+};
+
+struct mmo_charstatus {
+ int char_id;
+ int account_id;
+ int base_exp,job_exp,zeny;
+
+ short class;
+ short status_point,skill_point;
+ short hp,max_hp,sp,max_sp;
+ short option,karma,manner;
+ short hair,hair_color,clothes_color;
+ int party_id,guild_id,pet_id;
+
+ short weapon,shield;
+ short head_top,head_mid,head_bottom;
+
+ char name[24];
+ unsigned char base_level,job_level;
+ unsigned char str,agi,vit,int_,dex,luk,char_num,sex;
+
+ struct point last_point,save_point,memo_point[3];
+ struct item inventory[MAX_INVENTORY],cart[MAX_CART];
+ struct skill skill[MAX_SKILL];
+ int global_reg_num;
+ struct global_reg global_reg[GLOBAL_REG_NUM];
+};
+
+int mmo_char_tostr(char *str,struct mmo_charstatus *p)
+{
+ int i;
+ sprintf(str,"%d\t%d,%d\t%s\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d\t%d,%d,%d,%d,%d,%d\t%d,%d"
+ "\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d,%d"
+ "\t%s,%d,%d\t%s,%d,%d",
+ p->char_id,p->account_id,p->char_num,p->name, //
+ p->class,p->base_level,p->job_level,
+ p->base_exp,p->job_exp,p->zeny,
+ p->hp,p->max_hp,p->sp,p->max_sp,
+ p->str,p->agi,p->vit,p->int_,p->dex,p->luk,
+ p->status_point,p->skill_point,
+ p->option,p->karma,p->manner, //
+ p->party_id,p->guild_id,p->pet_id,
+ p->hair,p->hair_color,p->clothes_color,
+ p->weapon,p->shield,p->head_top,p->head_mid,p->head_bottom,
+ p->last_point.map,p->last_point.x,p->last_point.y, //
+ p->save_point.map,p->save_point.x,p->save_point.y
+ );
+ strcat(str,"\t");
+ for(i=0;i<3;i++)
+ if(p->memo_point[i].map[0]){
+ sprintf(str+strlen(str),"%s,%d,%d",p->memo_point[i].map,p->memo_point[i].x,p->memo_point[i].y);
+ }
+ strcat(str,"\t");
+ for(i=0;i<MAX_INVENTORY;i++)
+ if(p->inventory[i].nameid){
+ sprintf(str+strlen(str),"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d ",
+ p->inventory[i].id,p->inventory[i].nameid,p->inventory[i].amount,p->inventory[i].equip,
+ p->inventory[i].identify,p->inventory[i].refine,p->inventory[i].attribute,
+ p->inventory[i].card[0],p->inventory[i].card[1],p->inventory[i].card[2],p->inventory[i].card[3]);
+ }
+ strcat(str,"\t");
+ for(i=0;i<MAX_CART;i++)
+ if(p->cart[i].nameid){
+ sprintf(str+strlen(str),"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d ",
+ p->cart[i].id,p->cart[i].nameid,p->cart[i].amount,p->cart[i].equip,
+ p->cart[i].identify,p->cart[i].refine,p->cart[i].attribute,
+ p->cart[i].card[0],p->cart[i].card[1],p->cart[i].card[2],p->cart[i].card[3]);
+ }
+ strcat(str,"\t");
+ for(i=0;i<MAX_SKILL;i++)
+ if(p->skill[i].id){
+ sprintf(str+strlen(str),"%d,%d ",p->skill[i].id,p->skill[i].lv);
+ }
+ strcat(str,"\t");
+ for(i=0;i<p->global_reg_num;i++)
+ sprintf(str+strlen(str),"%s,%d ",p->global_reg[i].str,p->global_reg[i].value);
+ strcat(str,"\t");
+ return 0;
+}
+
+int mmo_char_fromstr(char *str,struct mmo_charstatus *p)
+{
+ int tmp_int[256];
+ int set,next,len,i;
+
+ set=sscanf(str,"%d\t%d,%d\t%[^\t]\t%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d\t%d,%d,%d,%d,%d,%d\t%d,%d"
+ "\t%d,%d,%d\t%d,%d\t%d,%d,%d\t%d,%d,%d,%d,%d"
+ "\t%[^,],%d,%d\t%[^,],%d,%d%n",
+ &tmp_int[0],&tmp_int[1],&tmp_int[2],p->name, //
+ &tmp_int[3],&tmp_int[4],&tmp_int[5],
+ &tmp_int[6],&tmp_int[7],&tmp_int[8],
+ &tmp_int[9],&tmp_int[10],&tmp_int[11],&tmp_int[12],
+ &tmp_int[13],&tmp_int[14],&tmp_int[15],&tmp_int[16],&tmp_int[17],&tmp_int[18],
+ &tmp_int[19],&tmp_int[20],
+ &tmp_int[21],&tmp_int[22],&tmp_int[23], //
+ &tmp_int[24],&tmp_int[25],
+ &tmp_int[26],&tmp_int[27],&tmp_int[28],
+ &tmp_int[29],&tmp_int[30],&tmp_int[31],&tmp_int[32],&tmp_int[33],
+ p->last_point.map,&tmp_int[34],&tmp_int[35], //
+ p->save_point.map,&tmp_int[36],&tmp_int[37],&next
+ );
+ p->char_id=tmp_int[0];
+ p->account_id=tmp_int[1];
+ p->char_num=tmp_int[2];
+ p->class=tmp_int[3];
+ p->base_level=tmp_int[4];
+ p->job_level=tmp_int[5];
+ p->base_exp=tmp_int[6];
+ p->job_exp=tmp_int[7];
+ p->zeny=tmp_int[8];
+ p->hp=tmp_int[9];
+ p->max_hp=tmp_int[10];
+ p->sp=tmp_int[11];
+ p->max_sp=tmp_int[12];
+ p->str=tmp_int[13];
+ p->agi=tmp_int[14];
+ p->vit=tmp_int[15];
+ p->int_=tmp_int[16];
+ p->dex=tmp_int[17];
+ p->luk=tmp_int[18];
+ p->status_point=tmp_int[19];
+ p->skill_point=tmp_int[20];
+ p->option=tmp_int[21];
+ p->karma=tmp_int[22];
+ p->manner=tmp_int[23];
+ p->party_id=tmp_int[24];
+ p->guild_id=tmp_int[25];
+ p->pet_id=0;
+ p->hair=tmp_int[26];
+ p->hair_color=tmp_int[27];
+ p->clothes_color=tmp_int[28];
+ p->weapon=tmp_int[29];
+ p->shield=tmp_int[30];
+ p->head_top=tmp_int[31];
+ p->head_mid=tmp_int[32];
+ p->head_bottom=tmp_int[33];
+ p->last_point.x=tmp_int[34];
+ p->last_point.y=tmp_int[35];
+ p->save_point.x=tmp_int[36];
+ p->save_point.y=tmp_int[37];
+ if(set!=41)
+ return 0;
+ if(str[next]=='\n' || str[next]=='\r')
+ return 1; // V‹Kƒf[ƒ^
+ next++;
+ for(i=0;str[next] && str[next]!='\t';i++){
+ set=sscanf(str+next,"%[^,],%d,%d%n",p->memo_point[i].map,&tmp_int[0],&tmp_int[1],&len);
+ if(set!=3)
+ return 0;
+ p->memo_point[i].x=tmp_int[0];
+ p->memo_point[i].y=tmp_int[1];
+ next+=len;
+ if(str[next]==' ')
+ next++;
+ }
+ next++;
+ for(i=0;str[next] && str[next]!='\t';i++){
+ set=sscanf(str+next,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
+ &tmp_int[0],&tmp_int[1],&tmp_int[2],&tmp_int[3],
+ &tmp_int[4],&tmp_int[5],&tmp_int[6],
+ &tmp_int[7],&tmp_int[8],&tmp_int[9],&tmp_int[10],&len);
+ if(set!=11)
+ return 0;
+ p->inventory[i].id=tmp_int[0];
+ p->inventory[i].nameid=tmp_int[1];
+ p->inventory[i].amount=tmp_int[2];
+ p->inventory[i].equip=tmp_int[3];
+ p->inventory[i].identify=tmp_int[4];
+ p->inventory[i].refine=tmp_int[5];
+ p->inventory[i].attribute=tmp_int[6];
+ p->inventory[i].card[0]=tmp_int[7];
+ p->inventory[i].card[1]=tmp_int[8];
+ p->inventory[i].card[2]=tmp_int[9];
+ p->inventory[i].card[3]=tmp_int[10];
+ next+=len;
+ if(str[next]==' ')
+ next++;
+ }
+ next++;
+ for(i=0;str[next] && str[next]!='\t';i++){
+ set=sscanf(str+next,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
+ &tmp_int[0],&tmp_int[1],&tmp_int[2],&tmp_int[3],
+ &tmp_int[4],&tmp_int[5],&tmp_int[6],
+ &tmp_int[7],&tmp_int[8],&tmp_int[9],&tmp_int[10],&len);
+ if(set!=11)
+ return 0;
+ p->cart[i].id=tmp_int[0];
+ p->cart[i].nameid=tmp_int[1];
+ p->cart[i].amount=tmp_int[2];
+ p->cart[i].equip=tmp_int[3];
+ p->cart[i].identify=tmp_int[4];
+ p->cart[i].refine=tmp_int[5];
+ p->cart[i].attribute=tmp_int[6];
+ p->cart[i].card[0]=tmp_int[7];
+ p->cart[i].card[1]=tmp_int[8];
+ p->cart[i].card[2]=tmp_int[9];
+ p->cart[i].card[3]=tmp_int[10];
+ next+=len;
+ if(str[next]==' ')
+ next++;
+ }
+ next++;
+ for(i=0;str[next] && str[next]!='\t';i++){
+ set=sscanf(str+next,"%d,%d%n",
+ &tmp_int[0],&tmp_int[1],&len);
+ if(set!=2)
+ return 0;
+ p->skill[tmp_int[0]].id=tmp_int[0];
+ p->skill[tmp_int[0]].lv=tmp_int[1];
+ next+=len;
+ if(str[next]==' ')
+ next++;
+ }
+ next++;
+ for(i=0;str[next] && str[next]!='\t' && str[next]!='\n' && str[next]!='\r';i++){ //global_regŽÀ‘•ˆÈ‘O‚Ìathena.txtŒÝŠ·‚Ì‚½‚߈ꉞ'\n'ƒ`ƒFƒbƒN
+ set=sscanf(str+next,"%[^,],%d%n",
+ p->global_reg[i].str,&p->global_reg[i].value,&len);
+ if(set!=2)
+ return 0;
+ next+=len;
+ if(str[next]==' ')
+ next++;
+ }
+ p->global_reg_num=i;
+ return 1;
+}
+
+int mmo_char_convert(char *fname1,char *fname2)
+{
+ char line[65536];
+ int ret;
+ struct mmo_charstatus char_dat;
+ FILE *ifp,*ofp;
+
+ ifp=fopen(fname1,"r");
+ ofp=fopen(fname2,"w");
+ if(ifp==NULL) {
+ printf("file not found %s\n",fname1);
+ return 0;
+ }
+ if(ofp==NULL) {
+ printf("file open error %s\n",fname2);
+ return 0;
+ }
+ while(fgets(line,65535,ifp)){
+ memset(&char_dat,0,sizeof(struct mmo_charstatus));
+ ret=mmo_char_fromstr(line,&char_dat);
+ if(ret){
+ mmo_char_tostr(line,&char_dat);
+ fprintf(ofp,"%s" RETCODE,line);
+ }
+ }
+ fcloseall();
+ return 0;
+}
+
+int main(int argc,char *argv[])
+{
+ if(argc < 3) {
+ printf("Usage: convert <input filename> <output filename>\n");
+ exit(0);
+ }
+ mmo_char_convert(argv[1],argv[2]);
+
+ return 0;
+}
diff --git a/src/tool/getlogincount b/src/tool/getlogincount
new file mode 100644
index 000000000..45c6f81f6
--- /dev/null
+++ b/src/tool/getlogincount
@@ -0,0 +1,122 @@
+#!/usr/bin/perl -w
+
+##########################################################################
+# INFORMATION TOOL ABOUT THE # OF ONLINE PLAYERS ON ATHENA SERVERS
+#
+# By connection on the athena login-server, this software displays the
+# number of online players.
+#
+#-------------------------------------------------------------------------
+# Software usage:
+# Configure the IP, the port and a valid account of the server.
+# After, use at your choice:
+# ./getlogincount - display the number of online players on all servers.
+# ./getlogincount --premier or
+# ./getlogincount --first -- display the number of online players of the
+# first server in the received list.
+# ./getlogincount [servername] -- display the number of online players
+# of the specified server.
+#
+# If successfull, the software return the value 0.
+#
+##########################################################################
+
+#------------------------------ CONFIGURATION ----------------------------
+
+$loginserverip = "127.0.0.1"; # IP of the login-server
+$loginserverport = 6900; # port of the login-server
+$loginaccount = "s1"; # a valid account name
+$loginpasswd = "p1"; # the password of the valid account name
+
+$connecttimeout = 10; # Connection timeout (in seconds)
+
+#-------------------------------------------------------------------------
+
+use IO::Socket;
+
+my($sname) = $ARGV[0];
+if (!defined($sname)) {
+ $sname = "";
+}
+
+# Connection to the login-server
+my($so,$er) = ();
+eval{
+ $so = IO::Socket::INET->new(
+ PeerAddr=> $loginserverip,
+ PeerPort=> $loginserverport,
+ Proto => "tcp",
+ Timeout => $connecttimeout) or $er=1;
+};
+if($er || $@){
+ print "Can't not connect to the login-server [${loginserverip}:$loginserverport] !\n";
+ exit(2);
+}
+
+# Request to connect on login-server
+print $so pack("v V a24 a24 C",0x0064,9,$loginaccount,$loginpasswd,3);
+$so->flush();
+
+# Fail to connect
+if(unpack("v", &soread(\$so,2)) != 0x0069) {
+ print "Login error.\n";
+ exit(3);
+}
+
+# Get length of the received packet
+my($plen) = unpack("v",&soread(\$so,2))-4;
+
+# Suppress information of the account (we need only information about the servers)
+&soread(\$so,43);
+$plen -= 43;
+
+# Check about the number of online servers
+if ($plen < 32) {
+ printf "No server is connected to login-server.\n";
+ exit(1);
+}
+
+# Read information of the servers
+my(@slist) = ();
+for(;$plen > 0;$plen -= 32) {
+ my($name,$count) = unpack("x6 a20 V",&soread(\$so,32));
+ $name = substr($name,0,index($name,"\0"));
+ push @slist, [ $name, $count ];
+}
+
+# Display the result
+if($sname eq "--first" || $sname eq "--premier") { # If we ask only for the first server
+ printf "%-20s : %5d\n",$slist[0][0],$slist[0][1];
+} elsif ($sname eq "") { # If we ask for all servers
+ foreach $i(@slist) {
+ printf "%-20s : %5d\n",$i->[0],$i->[1];
+ }
+} else { # If we ask for a specified server (by its name)
+ my($flag) = 1;
+ foreach $i(@slist) {
+ if($i->[0] eq $sname) {
+ printf "%-20s : %5d\n",$i->[0],$i->[1];
+ $flag = 0;
+ }
+ }
+ if($flag) { # If the server doesn't exist
+ printf "The server [$sname] doesn't exist.\n";
+ exit(1);
+ }
+}
+
+# End of the software
+$so->shutdown(2);
+$so->close();
+exit(0);
+
+# Sub-function: get data from the socket
+sub soread {
+ my($so,$len) = @_;
+ my($sobuf);
+ if(read($$so,$sobuf,$len) < $len) {
+ print "Socket read error.\n";
+ exit(5);
+ }
+ return $sobuf;
+};
diff --git a/src/tool/ladmin b/src/tool/ladmin
new file mode 100644
index 000000000..d0c0be485
--- /dev/null
+++ b/src/tool/ladmin
@@ -0,0 +1,3793 @@
+#!/usr/bin/perl
+use POSIX;
+##########################################################################
+# EAthena login-server remote administration tool
+# New ladamin by [Yor]
+##########################################################################
+#-------------------------------INSTRUCTIONS------------------------------
+# Set the 4 variables below:
+# IP of the login server.
+# Port where the login-server listens incoming packets.
+# Password of administration (same of config_athena.conf).
+# Displayed language of the sofware (if not correct, english is used).
+# IMPORTANT:
+# Be sure that you authorize remote administration in login-server
+# (see login_athena.conf, 'admin_state' parameter)
+#-------------------------------------------------------------------------
+my($loginserverip) = "127.0.0.1"; # IP of login-server
+my($loginserverport) = 6900; # Port of login-server
+my($loginserveradminpassword) = "admin"; # Administration password
+my($connecttimeout) = 10; # Timeout of connection (in seconds)
+my($passenc) = 2; # Encoding type of the password
+my($defaultlanguage) = "E"; # Default language (F: Français/E: English)
+ # (if it's not 'F', default is English)
+
+#-------------------------------------------------------------------------
+# LIST of COMMANDs that you can type at the prompt:
+# To use these commands you can only type only the first letters.
+# You must type a minimum of letters (you can not type 'a',
+# because ladmin doesn't know if it's for 'aide' or for 'add')
+# <Example> q <= quit, li <= list, pass <= passwd, etc.
+#
+# Note: every time you must give a account_name, you can use "" or '' (spaces can be included)
+#
+# aide/help/?
+# Display the description of the commands
+# aide/help/? [command]
+# Display the description of the specified command
+#
+# add <account_name> <sex> <password>
+# Create an account with the default email (a@a.com).
+# Concerning the sex, only the first letter is used (F or M).
+# The e-mail is set to a@a.com (default e-mail). It's like to have no e-mail.
+# When the password is omitted, the input is done without displaying of the pressed keys.
+# <example> add testname Male testpass
+#
+# ban/banish yyyy/mm/dd hh:mm:ss <account name>
+# Changes the final date of a banishment of an account.
+# Same command of banset, except that account_name is at end
+#
+# banadd <account_name> <modifier>
+# Adds or substracts time from the final date of a banishment of an account.
+# Modifier is done as follows:
+# Adjustment value (-1, 1, +1, etc...)
+# Modified element:
+# a or y: year
+# m: month
+# j or d: day
+# h: hour
+# mn: minute
+# s: second
+# <example> banadd testname +1m-2mn1s-6y
+# this example adds 1 month and 1 second, and substracts 2 minutes and 6 years at the same time.
+# NOTE: If you modify the final date of a non-banished account,
+# you fix the final date to (actual time +- adjustments)
+#
+# banset <account_name> yyyy/mm/dd [hh:mm:ss]
+# Changes the final date of a banishment of an account.
+# Default time: 23:59:59
+# banset <account_name> 0
+# Set a non-banished account (0 = unbanished).
+#
+# block <account name>
+# Set state 5 (You have been blocked by the GM Team) to an account.
+# Same command of state <account_name> 5.
+#
+# check <account_name> <password>
+# Check the validity of a password for an account
+# NOTE: Server will never sends back a password.
+# It's the only method you have to know if a password is correct.
+# The other method is to have a ('physical') access to the accounts file.
+#
+# create <account_name> <sex> <email> <password>
+# Like the 'add' command, but with e-mail moreover.
+# <example> create testname Male my@mail.com testpass
+#
+# del <account name>
+# Remove an account.
+# This order requires confirmation. After confirmation, the account is deleted.
+#
+# email <account_name> <email>
+# Modify the e-mail of an account.
+#
+# getcount
+# Give the number of players online on all char-servers.
+#
+# gm <account_name> [GM_level]
+# Modify the GM level of an account.
+# Default value remove GM level (GM level = 0).
+# <example> gm testname 80
+#
+# id <account name>
+# Give the id of an account.
+#
+# info <account_id>
+# Display complete information of an account.
+#
+# kami <message>
+# Sends a broadcast message on all map-server (in yellow).
+# kamib <message>
+# Sends a broadcast message on all map-server (in blue).
+#
+# language <language>
+# Change the language of displaying.
+#
+# list/ls [start_id [end_id]]
+# Display a list of accounts.
+# 'start_id', 'end_id': indicate end and start identifiers.
+# Research by name is not possible with this command.
+# <example> list 10 9999999
+#
+# listBan/lsBan [start_id [end_id]]
+# Like list/ls, but only for accounts with state or banished
+#
+# listGM/lsGM [start_id [end_id]]
+# Like list/ls, but only for GM accounts
+#
+# listOK/lsOK [start_id [end_id]]
+# Like list/ls, but only for accounts without state and not banished
+#
+# memo <account_name> <memo>
+# Modify the memo of an account.
+# 'memo': it can have until 253 characters (with spaces or not).
+#
+# name <account_id>
+# Give the name of an account.
+#
+# passwd <account_name> <new_password>
+# Change the password of an account.
+# When new password is omitted, the input is done without displaying of the pressed keys.
+#
+# quit/end/exit
+# End of the program of administration
+#
+# reloadGM
+# Reload GM configuration file
+#
+# search <expression>
+# Seek accounts.
+# Displays the accounts whose names correspond.
+# search -r/-e/--expr/--regex <expression>
+# Seek accounts by regular expression.
+# Displays the accounts whose names correspond.
+#
+# sex <account_name> <sex>
+# Modify the sex of an account.
+# <example> sex testname Male
+#
+# state <account_name> <new_state> <error_message_#7>
+# Change the state of an account.
+# 'new_state': state is the state of the packet 0x006a + 1. The possibilities are:
+# 0 = Account ok 6 = Your Game's EXE file is not the latest version
+# 1 = Unregistered ID 7 = You are Prohibited to log in until %s
+# 2 = Incorrect Password 8 = Server is jammed due to over populated
+# 3 = This ID is expired 9 = No MSG
+# 4 = Rejected from Server 100 = This ID has been totally erased
+# 5 = You have been blocked by the GM Team
+# all other values are 'No MSG', then use state 9 please.
+# 'error_message_#7': message of the code error 6 = Your are Prohibited to log in until %s (packet 0x006a)
+#
+# timeadd <account_name> <modifier>
+# Adds or substracts time from the validity limit of an account.
+# Modifier is done as follows:
+# Adjustment value (-1, 1, +1, etc...)
+# Modified element:
+# a or y: year
+# m: month
+# j or d: day
+# h: hour
+# mn: minute
+# s: second
+# <example> timeadd testname +1m-2mn1s-6y
+# this example adds 1 month and 1 second, and substracts 2 minutes and 6 years at the same time.
+# NOTE: You can not modify a unlimited validity limit.
+# If you want modify it, you want probably create a limited validity limit.
+# So, at first, you must set the validity limit to a date/time.
+#
+# timeset <account_name> yyyy/mm/dd [hh:mm:ss]
+# Changes the validity limit of an account.
+# Default time: 23:59:59
+# timeset <account_name> 0
+# Gives an unlimited validity limit (0 = unlimited).
+#
+# unban/unbanish <account name>
+# Unban an account.
+# Same command of banset 0.
+#
+# unblock <account name>
+# Set state 0 (Account ok) to an account.
+# Same command of state <account_name> 0.
+#
+# version
+# Display the version of the login-server.
+#
+# who <account name>
+# Displays complete information of an account.
+#
+#-------------------------------------------------------------------------
+# Possibilities to execute ladmin in command line by usage of the software with a parameter:
+# ./ladmin --mode param1 ...
+#
+# --makesymlink -- Create the symbolic links for a use in shell
+# --add <account_name> <sex> <password> -- Create an account with the default email (or -a)
+# --ban yyyy/mm/dd hh:mm:ss <account_name> -- Change the final date of a banishment of an account (or -b)
+# --banadd <account_name> <modifier> -- Add or substract time from the final date of a banishment of an account (or - ba)
+# --banset <account_name> yyyy/mm/dd [hh:mm:ss] -- Change the final date of a banishment of an account (or -bs)
+# --banset <account_name> 0 -- Unbanish an account (or -bs)
+# --block <account_name> -- Set state 5 to an account (or -bl)
+# --check <account_name> <password> -- Check the validity of a password for an account (or -check)
+# --create <account_name> <sex> <email> <password> -- Create an account with email (or -c)
+# --del <account_name> -- Remove an account (or -d)
+# --email <account_name> <email> -- Modify an email of an account (or -e)
+# --getcount -- Give the number of players online on all char-servers (or -g)
+# --gm <account_name> <GM_level> -- Change the GM level of an account (or -gm)
+# --id <account_name> -- Give the id of an account (or -i)
+# --info <account_id> -- Display complete information of an account (or -info)
+# --kami <message> -- Sends a broadcast message on all map-server (in yellow).
+# --kamib <message> -- Sends a broadcast message on all map-server (in blue).
+# --language <language> -- Change the language of displaying (-lang).
+# --list [First_id [Last_id]] -- Display a list of accounts (or -l)
+# --listBan [start_id [end_id]] -- Display a list of accounts with state or banished (or -lBan)
+# --listGM [First_id [Last_id]] -- Display a list of GM accounts (or -lGM)
+# --listOK [start_id [end_id]] -- Display a list of accounts without state and not banished (or -lOK)
+# --memo <account_name> <memo> -- Modify the memo of an account (or -e)
+# --name <account_id> -- Give the name of an account (or -n)
+# --passwd <account_name> <new_password> -- Change the password of an account (or -p)
+# --reloadGM -- Reload GM configuration file (or -r)
+# --search <expression> -- Seek accounts (or -s)
+# --search -e/-r/--expr/--regex <expression> -- Seek accounts by REGEX (or -s)
+# --sex <account_name> <sex> -- Change the sex of an account (or -sex)
+# --state <account_name> <new_state> <error_message_#7> -- Change the state of an account (or -t)
+# --timeadd <account_name> <modifier> -- Add or substract time from the validity limit of an account (or - ta)
+# --timeset <account_name> yyyy/mm/dd [hh:mm:ss] -- Change the validify limit of an account (or -ts)
+# --timeset <account_name> 0 -- Give a unlimited validity limit (or -ts)
+# --unban/unbanish <account_name> -- Unban an account (or -uba)
+# --unblock <account_name> -- Set state 0 to an account (or -ubl)
+# --version -- Display the version of the login-server (or -v)
+# --who <account_name> -- Display complete information of an account (or -w)
+#
+# <example> ./ladmin --addaccount testname Male testpass
+#
+#-------------------------------------------------------------------------
+# Possibilities to execute ladmin with symbolic links in Shell
+# To create the symbolic links, execute ladmin with the '-- makesymlink' option.
+#
+# addaccount <account_name> <sex> <password> -- Create an account with the default email
+# banaccount yyyy/mm/dd hh:mm:ss <account_name> -- Change the final date of a banishment of an account
+# banaddaccount <account_name> <modifier> -- Add or substract time from the final date of a banishment of an account
+# bansetaccount <account_name> yyyy/mm/dd [hh:mm:ss] -- Change the final date of a banishment of an account
+# bansetaccount <account_name> 0 -- Unbanish an account
+# blockaccount <account_name> -- Set state 5 (blocked by the GM Team) to an account
+# checkaccount <account_name> <password> -- Check the validity of a password for an account
+# createaccount <account_name> <sex> <email> <password> -- Create an account with email
+# delaccount <account_name> -- Remove an account
+# emailaccount <account_name> <email> -- Modify an email of an account
+# getcount -- Give the number of players online on all char-servers
+# gmaccount <account_name> <GM_level> -- Change the GM level of an account
+# idaccount <account_name> -- Give the id of an account
+# infoaccount <account_id> -- Display complete information of an account
+# kami <message> -- Sends a broadcast message on all map-server (in yellow).
+# kamib <message> -- Sends a broadcast message on all map-server (in blue).
+# ladminlanguage <language> -- Change the language of displaying.
+# listaccount [First_id [Last_id]] -- Display a list of accounts
+# listBanaccount [start_id [end_id]] -- Display a list of accounts with state or banished
+# listGMaccount [First_id [Last_id]] -- Display a list of GM accounts
+# listOKaccount [start_id [end_id]] -- Display a list of accounts without state and not banished
+# loginserverversion -- Display the version of the login-server
+# memoaccount <account_name> <memo> -- Modify the memo of an account
+# nameaccount <account_id> -- Give the name of an account
+# passwdaccount <account_name> <new_password> -- Change the password of an account
+# reloadGM -- Reload GM configuration file
+# searchaccount <expression> -- Seek accounts
+# searchaccount -e/-r/--expr/--regex <expression> -- Seek accounts by REGEX
+# sexaccount <account_name> <sex> -- Change the sex of an account (or -sex)
+# stateaccount <account_name> <new_state> <error_message_#7> -- Change the state of an account
+# timeaddaccount <account_name> <modifier> -- Add or substract time from the validity limit of an account
+# timesetaccount <account_name> yyyy/mm/dd [hh:mm:ss] -- Change the validify limit of an account
+# timesetaccount <account_name> 0 -- Give a unlimited validity limit
+# unbanaccount <account_name> -- Unban an account
+# unblockaccount <account_name> -- Set state 0 (Account ok) to an account
+# whoaccount <account_name> -- Display complete information of an account
+# <exemple> ./addaccount testname Male testpass
+#
+#-------------------------------------------------------------------------
+# About the encoding:
+#
+# The Digest::MD5 module is necessary to use the encrypted password system.
+# When the software cannot found the Digest::MD5 module,
+# encoding is automatically disabled ($passenc=0), which allows
+# to use this program in any cases.
+#
+#-------------------------------------------------------------------------
+# How to use ladmin with UNIX:
+#
+# You excecute ladmin as a standard command.
+# <Example of preparation to have an access to ladmin>
+# $ mv ladmin ladmin_org
+# $ nkf -eLu ladmin_org > ladmin
+# $ chmod 700 ladmin
+# <Example to start directly ladmin>
+# $ perl ladmin
+#
+##########################################################################
+
+
+use strict;
+use IO::Socket;
+use Term::ReadLine;
+eval { use POSIX qw(:termios_h); };
+eval { use Digest::MD5 qw(md5); } if $passenc;
+$passenc = 0 if($@);
+
+my($ver) = "1.00";
+
+# Start of termios
+my($termios, $orgterml, $termlecho, $termlnoecho) = ();
+eval{
+ $termios = POSIX::Termios->new();
+ $termios->getattr(fileno(STDIN));
+ $orgterml = $termios->getlflag();
+ $termlecho = ECHO | ECHOK | ICANON;
+ $termlnoecho = $orgterml & ~$termlecho;
+};
+
+# Modification of termios for the displaying of passwords (no displays for pressed keys)
+sub cbreak() {
+ if ($termios) {
+ $termios->setlflag($termlnoecho);
+ $termios->setcc(VTIME, 1);
+ $termios->setattr(fileno(STDIN), TCSANOW);
+ }
+}
+# Modification of termios to return at the normal displaying (after input of the passwords)
+sub cooked() {
+ if ($termios) {
+ $termios->setlflag($orgterml);
+ $termios->setcc(VTIME,0);
+ $termios->setattr(fileno(STDIN),TCSANOW);
+ }
+}
+END{ cooked() }
+
+if ($defaultlanguage eq "F") {
+ print "Outil d'administration à distance de eAthena V.$ver\n";
+} else {
+ print "EAthena login-server administration tool V.$ver\n";
+}
+
+# Creation of the symbolic links for call of the program in line command of the shell
+if ($ARGV[0] eq "--makesymlink") {
+ symlink $0, "loginserverversion";
+ symlink $0, "addaccount";
+ symlink $0, "banaccount";
+ symlink $0, "banaddaccount";
+ symlink $0, "bansetaccount";
+ symlink $0, "blockaccount";
+ symlink $0, "checkaccount";
+ symlink $0, "createaccount";
+ symlink $0, "delaccount";
+ symlink $0, "emailaccount";
+ symlink $0, "getcount";
+ symlink $0, "gmaccount";
+ symlink $0, "idaccount";
+ symlink $0, "infoaccount";
+ symlink $0, "kami";
+ symlink $0, "kamib";
+ symlink $0, "ladminlanguage";
+ symlink $0, "listaccount";
+ symlink $0, "listBanaccount";
+ symlink $0, "listGMaccount";
+ symlink $0, "listOKaccount";
+ symlink $0, "memoaccount";
+ symlink $0, "nameaccount";
+ symlink $0, "passwdaccount";
+ symlink $0, "reloadGM";
+ symlink $0, "searchaccount";
+ symlink $0, "sexaccount";
+ symlink $0, "stateaccount";
+ symlink $0, "timeaddaccount";
+ symlink $0, "timesetaccount";
+ symlink $0, "unbanaccount";
+ symlink $0, "unblockaccount";
+ symlink $0, "whoaccount";
+ if ($defaultlanguage eq "F") {
+ print "Liens symbliques créés.\n";
+ } else {
+ print "Symbolic links created.\n";
+ }
+ exit(0);
+}
+
+# Connection to the login-server
+my($so,$er) = ();
+eval{
+ $so = IO::Socket::INET->new(
+ PeerAddr=> $loginserverip,
+ PeerPort=> $loginserverport,
+# Proto => "tcp",
+ Timeout => $connecttimeout) or $er = 1;
+};
+if ($er || $@) {
+ if ($defaultlanguage eq "F") {
+ print "\nImpossible de se connecter au serveur de login [${loginserverip}:$loginserverport] !\n";
+ } else {
+ print "\nImpossible to have a connection with the login-server [${loginserverip}:$loginserverport] !\n";
+ }
+ print "$!\n"; # Displaying of the error
+ exit(2);
+}
+
+# Sending the administration password
+if ($passenc == 0) {
+ print $so pack("v2a24",0x7918,0,$loginserveradminpassword);
+ $so->flush();
+} else {
+ print $so pack("v",0x791a);
+ $so->flush();
+ my($buf) = readso(4);
+ if (unpack("v",$buf) != 0x01dc) {
+ if ($defaultlanguage eq "F") {
+ print "Erreur au login (échec de la création de la clef md5).\n";
+ } else {
+ print "Error at login (failure of the md5 key creation).\n";
+ }
+ }
+ $buf = readso(unpack("x2v",$buf)-4);
+ my($md5bin) = md5(($passenc == 1) ? $buf.$loginserveradminpassword : $loginserveradminpassword.$buf);
+ print $so pack("v2a16",0x7918,$passenc,$md5bin);
+ $so->flush();
+}
+
+# Waiting of the server reply
+my($buf) = readso(3);
+
+if (unpack("v",$buf) != 0x7919 || unpack("x2c",$buf) != 0) {
+ if ($defaultlanguage eq "F") {
+ print "Erreur de login:\n";
+ print " - mot de passe incorrect,\n";
+ print " - système d'administration non activé, ou\n";
+ print " - IP non autorisée.\n";
+ } else {
+ print "Error at login:\n";
+ print " - incorrect password,\n";
+ print " - administration system not activated, or\n";
+ print " - unauthorised IP.\n";
+ }
+ quit();
+ exit(4);
+}
+
+if ($defaultlanguage eq "F") {
+ print "Connexion établie.\n";
+} else {
+ print "Established connection.\n";
+}
+
+#-------------------------------------------------------------------------
+# Here are checked the command lines with arguments and symbolic links (no prompt)
+
+if ($0 =~ /addaccount$/ ||
+ (($ARGV[0] eq "-a" || $ARGV[0] eq "--add") && ((shift @ARGV), 1))) {
+ my($r) = addaccount($ARGV[0], $ARGV[1], $ARGV[2]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /banaccount$/ || $0 =~ /banishaccount$/ ||
+ (($ARGV[0] eq "-b" || $ARGV[0] eq "--ban" || $ARGV[0] eq "--banish") && ((shift @ARGV), 1))) {
+ my($r) = bansetaccount($ARGV[1], $ARGV[2], $ARGV[0]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /banaddaccount$/ ||
+ (($ARGV[0] eq "-ba" || $ARGV[0] eq "--banadd") && ((shift @ARGV), 1))) {
+ my($r) = banaddaccount($ARGV[0], $ARGV[1]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /bansetaccount$/ ||
+ (($ARGV[0] eq "-bs" || $ARGV[0] eq "--banset") && ((shift @ARGV), 1))) {
+ my($r) = bansetaccount($ARGV[0], $ARGV[1], $ARGV[2]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /blockaccount$/ ||
+ (($ARGV[0] eq "-bl" || $ARGV[0] eq "--block") && ((shift @ARGV), 1))) {
+ my($r) = changestate($ARGV[0], 5, "");
+ quit();
+ exit($r);
+} elsif ($0 =~ /checkaccount$/ ||
+ (($ARGV[0] eq "-check" || $ARGV[0] eq "--check") && ((shift @ARGV), 1))) {
+ my($r) = checkaccount($ARGV[0], $ARGV[1]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /createaccount$/ ||
+ (($ARGV[0] eq "-c" || $ARGV[0] eq "--create") && ((shift @ARGV), 1))) {
+ my($r) = createaccount($ARGV[0], $ARGV[1], $ARGV[2], $ARGV[3]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /delaccount$/ ||
+ (($ARGV[0] eq "-d" || $ARGV[0] eq "--del") && ((shift @ARGV), 1))) {
+ my($r) = delaccount($ARGV[0]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /emailaccount$/ ||
+ (($ARGV[0] eq "-e" || $ARGV[0] eq "--email") && ((shift @ARGV), 1))) {
+ my($r) = changeemail($ARGV[0], $ARGV[1]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /getcount$/ ||
+ (($ARGV[0] eq "-g" || $ARGV[0] eq "--getcount") && ((shift @ARGV), 1))) {
+ my($r) = getlogincount();
+ quit();
+ exit($r);
+} elsif ($0 =~ /gmaccount$/ ||
+ (($ARGV[0] eq "-gm" || $ARGV[0] eq "--gm") && ((shift @ARGV), 1))) {
+ my($r) = changegmlevel($ARGV[0], $ARGV[1]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /id$/ ||
+ (($ARGV[0] eq "-i" || $ARGV[0] eq "--id") && ((shift @ARGV), 1))) {
+ my($r) = idaccount($ARGV[0]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /infoaccount$/ ||
+ (($ARGV[0] eq "-info" || $ARGV[0] eq "--info") && ((shift @ARGV), 1))) {
+ my($r) = infoaccount($ARGV[0]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /kami$/ ||
+ (($ARGV[0] eq "-kami" || $ARGV[0] eq "--kami") && ((shift @ARGV), 1))) {
+ my($r) = sendbroadcast(0, $ARGV[0]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /kamib$/ ||
+ (($ARGV[0] eq "-kamib" || $ARGV[0] eq "--kamib") && ((shift @ARGV), 1))) {
+ my($r) = sendbroadcast(0x10, $ARGV[0]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /ladminlanguage$/ ||
+ (($ARGV[0] eq "-lang" || $ARGV[0] eq "--language") && ((shift @ARGV), 1))) {
+ my($r) = changelanguage($ARGV[0]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /listaccount$/ ||
+ (($ARGV[0] eq "-l" || $ARGV[0] eq "--list") && ((shift @ARGV), 1))) {
+ my($r) = listaccount(int($ARGV[0]), int($ARGV[1]), 0); # 0: to list all
+ quit();
+ exit($r);
+} elsif ($0 =~ /listBanaccount$/ ||
+ (($ARGV[0] eq "-lBan" || $ARGV[0] eq "--listBan") && ((shift @ARGV), 1))) {
+ my($r) = listaccount(int($ARGV[0]), int($ARGV[1]), 3); # 3: to list only accounts with state or banished
+ quit();
+ exit($r);
+} elsif ($0 =~ /listGMaccount$/ ||
+ (($ARGV[0] eq "-lGM" || $ARGV[0] eq "--listGM") && ((shift @ARGV), 1))) {
+ my($r) = listaccount(int($ARGV[0]), int($ARGV[1]), 1); # 1: to list only GM
+ quit();
+ exit($r);
+} elsif ($0 =~ /listOKaccount$/ ||
+ (($ARGV[0] eq "-lOK" || $ARGV[0] eq "--listOK") && ((shift @ARGV), 1))) {
+ my($r) = listaccount(int($ARGV[0]), int($ARGV[1]), 4); # 4: to list only accounts without state and not banished
+ quit();
+ exit($r);
+} elsif ($0 =~ /loginserverversion$/ ||
+ (($ARGV[0] eq "-v" || $ARGV[0] eq "--version") && ((shift @ARGV), 1))) {
+ my($r) = checkloginversion();
+ quit();
+ exit($r);
+} elsif ($0 =~ /memoaccount$/ ||
+ (($ARGV[0] eq "-m" || $ARGV[0] eq "--memo") && ((shift @ARGV), 1))) {
+ my($r) = changememo($ARGV[0], $ARGV[1]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /nameaccount$/ ||
+ (($ARGV[0] eq "-n" || $ARGV[0] eq "--name") && ((shift @ARGV), 1))) {
+ my($r) = nameaccount(int($ARGV[0]));
+ quit();
+ exit($r);
+} elsif ($0 =~ /passwdaccount$/ ||
+ (($ARGV[0] eq "-p" || $ARGV[0] eq "--passwd") && ((shift @ARGV), 1))) {
+ my($r) = changepasswd($ARGV[0], $ARGV[1]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /reloadGM$/ ||
+ (($ARGV[0] eq "-r" || $ARGV[0] eq "--reloadGM") && ((shift @ARGV), 1))) {
+ my($r) = reloadGM();
+ quit();
+ exit($r);
+} elsif ($0 =~ /searchaccount$/ ||
+ (($ARGV[0] eq "-s" || $ARGV[0] eq "--search") && ((shift @ARGV), 1))) {
+ my($r) = searchaccount($ARGV[0], $ARGV[1]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /sexaccount$/ ||
+ (($ARGV[0] eq "-sex" || $ARGV[0] eq "--sex") && ((shift @ARGV), 1))) {
+ my($r) = changesex($ARGV[0], $ARGV[1]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /stateaccount$/ ||
+ (($ARGV[0] eq "-t" || $ARGV[0] eq "--state") && ((shift @ARGV), 1))) {
+ my($r) = changestate($ARGV[0], $ARGV[1], $ARGV[2]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /timeaddaccount$/ ||
+ (($ARGV[0] eq "-ta" || $ARGV[0] eq "--timeadd") && ((shift @ARGV), 1))) {
+ my($r) = timeaddaccount($ARGV[0], $ARGV[1]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /timesetaccount$/ ||
+ (($ARGV[0] eq "-ts" || $ARGV[0] eq "--timeset") && ((shift @ARGV), 1))) {
+ my($r) = timesetaccount($ARGV[0], $ARGV[1], $ARGV[2]);
+ quit();
+ exit($r);
+} elsif ($0 =~ /unbanaccount$/ || $0 =~ /unbanishaccount$/ ||
+ (($ARGV[0] eq "-uba" || $ARGV[0] eq "--unban" || $ARGV[0] eq "--unbanish") && ((shift @ARGV), 1))) {
+ my($r) = bansetaccount($ARGV[0], 0, "");
+ quit();
+ exit($r);
+} elsif ($0 =~ /unblockaccount$/ ||
+ (($ARGV[0] eq "-ubl" || $ARGV[0] eq "--unblock") && ((shift @ARGV), 1))) {
+ my($r) = changestate($ARGV[0], 0, "");
+ quit();
+ exit($r);
+} elsif ($0 =~ /whoaccount$/ ||
+ (($ARGV[0] eq "-w" || $ARGV[0] eq "--who") && ((shift @ARGV), 1))) {
+ my($r) = whoaccount($ARGV[0]);
+ quit();
+ exit($r);
+}
+
+#-------------------------------------------------------------------------
+if ($defaultlanguage eq "F") {
+ print "Lecture de la version du serveur de login...\n";
+} else {
+ print "Reading of the version of the login-server...\n";
+}
+checkloginversion();
+
+# Set the prompt line
+my($term) = new Term::ReadLine "ladmin";
+
+# Here begin the infinite loop to read prompts
+while(1) {
+ # Displaying of the prompt
+ print "\n";
+ if ($defaultlanguage eq "F") {
+ printf "\033[32mPour afficher les commandes, tapez 'Entrée'.\033[0m\n";
+ } else {
+ printf "\033[32mTo list the commands, type 'enter'.\033[0m\n";
+ }
+ my($cmd) = $term->readline("ladmin> ");
+ # split and recovery of the input
+ chomp $cmd; # remove cariage return
+ $cmd =~ s/\x1b\[\d*\w//g; # remove (esc)[(number)(1alpha) = screen control sequence
+ $cmd =~ s/[\x00-\x1f]//g; # remove control char
+ my($command, $parameters) = split /\s+/,$cmd,2; # extract command and parameters
+ $command = lc($command); # command in lowercase
+ my(@paramlist) = split /\s+/,$parameters; # get list of parameters
+
+ if ($command eq "?" || $command eq "") {
+ $command = "aide" if ($defaultlanguage eq "F");
+ $command = "help" if ($defaultlanguage ne "F");
+ }
+
+ # Analyse of the command
+ eval {
+# help
+ if ("aide" =~ /^\Q$command/ && $command ne "a") { # check 1 letter command: 'aide' or 'add'?
+ displayhelp("aide", $paramlist[0]);
+ } elsif ("help" =~ /^\Q$command/) {
+ displayhelp("help", $paramlist[0]);
+
+# general commands
+ } elsif ("add" =~ /^\Q$command/ && $command ne "a") { # check 1 letter command: 'aide' or 'add'?
+ if (@paramlist = ($parameters =~ m/^"(.*)"\s+(\S+)\s+(.*)/)) {
+ addaccount($paramlist[0], $paramlist[1], $paramlist[2]); # <account_name> <sex> <password>
+ } elsif (@paramlist = ($parameters =~ m/^"(.*)"\s+(\S+)/)) {
+ addaccount($paramlist[0], $paramlist[1], ""); # <account_name> <sex> <password>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'\s+(\S+)\s+(.*)/)) {
+ addaccount($paramlist[0], $paramlist[1], $paramlist[2]); # <account_name> <sex> <password>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'\s+(\S+)/)) {
+ addaccount($paramlist[0], $paramlist[1], ""); # <account_name> <sex> <password>
+ } else {
+ @paramlist = split /\s+/,$parameters;
+ addaccount($paramlist[0], $paramlist[1], $paramlist[2]); # <account_name> <sex> <password>
+ }
+
+ } elsif ($command eq "ban" || ("banish" =~ /^\Q$command/ && length($command) >= 4)) {
+ if (@paramlist = ($parameters =~ m/^(\S+)\s+(\S+)\s+"(.*)"/)) { # yyyy/mm/dd hh:mm:ss <account_name>
+ bansetaccount($paramlist[2], $paramlist[0], $paramlist[1]); # <account_name> yyyy/mm/dd [hh:mm:ss]
+ } elsif (@paramlist = ($parameters =~ m/^(\S+)\s+(\S+)\s+'(.*)'/)) { # yyyy/mm/dd hh:mm:ss <account_name>
+ bansetaccount($paramlist[2], $paramlist[0], $paramlist[1]); # <account_name> yyyy/mm/dd [hh:mm:ss]
+ } else {
+ @paramlist = split /\s+/,$parameters,3; # yyyy/mm/dd hh:mm:ss <account_name>
+ bansetaccount($paramlist[2], $paramlist[0], $paramlist[1]); # <account_name> yyyy/mm/dd [hh:mm:ss]
+ }
+
+ } elsif (("banadd" =~ /^\Q$command/ || $command eq "ba") && $command ne "b") { # check 1 letter command: 'ba' or 'bs'?
+ if (@paramlist = ($parameters =~ m/^"(.*)"\s+(\S+)/)) {
+ banaddaccount($paramlist[0], $paramlist[1]); # <account_name> <modifier>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'\s+(\S+)/)) {
+ banaddaccount($paramlist[0], $paramlist[1]); # <account_name> <modifier>
+ } else {
+ @paramlist = split /\s+/,$parameters;
+ banaddaccount($paramlist[0], $paramlist[1]); # <account_name> <modifier>
+ }
+
+ } elsif (("banset" =~ /^\Q$command/ || $command eq "bs") && $command ne "b") { # check 1 letter command: 'ba' or 'bs'?
+ if (@paramlist = ($parameters =~ m/^"(.*)"\s+(\S+)\s+(\S+)/)) {
+ bansetaccount($paramlist[0], $paramlist[1], $paramlist[2]); # <account_name> yyyy/mm/dd [hh:mm:ss]
+ } elsif (@paramlist = ($parameters =~ m/^"(.*)"\s+(\S+)/)) {
+ bansetaccount($paramlist[0], $paramlist[1], "23:59:59"); # <account_name> yyyy/mm/dd [hh:mm:ss]
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'\s+(\S+)\s+(\S+)/)) {
+ bansetaccount($paramlist[0], $paramlist[1], $paramlist[2]); # <account_name> yyyy/mm/dd [hh:mm:ss]
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'\s+(\S+)/)) {
+ bansetaccount($paramlist[0], $paramlist[1], "23:59:59"); # <account_name> yyyy/mm/dd [hh:mm:ss]
+ } else {
+ @paramlist = split /\s+/,$parameters;
+ bansetaccount($paramlist[0], $paramlist[1], $paramlist[2]); # <account_name> yyyy/mm/dd [hh:mm:ss]
+ }
+
+ } elsif ("block" =~ /^\Q$command/ && length($command) >= 2) {
+ if (@paramlist = ($parameters =~ m/^"(.*)"/)) {
+ changestate($paramlist[0], 5, ""); # <account_name> <new_state> <error_message_#7>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'/)) {
+ changestate($paramlist[0], 5, ""); # <account_name> <new_state> <error_message_#7>
+ } else {
+ @paramlist = split /\s+/,$parameters,1;
+ changestate($paramlist[0], 5, ""); # <account_name> <new_state> <error_message_#7>
+ }
+
+ } elsif ("check" =~ /^\Q$command/ && $command ne "c") { # check 1 letter command: 'check' or 'create'?
+ if (@paramlist = ($parameters =~ m/^"(.*)"\s+(.*)/)) {
+ checkaccount($paramlist[0], $paramlist[1]); # <account_name> <password>
+ } elsif (@paramlist = ($parameters =~ m/^"(.*)"/)) {
+ checkaccount($paramlist[0], ""); # <account_name> <password>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'\s+(.*)/)) {
+ checkaccount($paramlist[0], $paramlist[1]); # <account_name> <password>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'/)) {
+ checkaccount($paramlist[0], ""); # <account_name> <password>
+ } else {
+ @paramlist = split /\s+/,$parameters;
+ checkaccount($paramlist[0], $paramlist[1]); # <account_name> <password>
+ }
+
+ } elsif ("create" =~ /^\Q$command/ && $command ne "c") { # check 1 letter command: 'check' or 'create'?
+ if (@paramlist = ($parameters =~ m/^"(.*)"\s+(\S+)\s+(\S+)\s+(.*)/)) {
+ createaccount($paramlist[0], $paramlist[1], $paramlist[2], $paramlist[3]); # <account_name> <sex> <email> <password>
+ } elsif (@paramlist = ($parameters =~ m/^"(.*)"\s+(\S+)\s+(\S+)/)) {
+ createaccount($paramlist[0], $paramlist[1], $paramlist[2], ""); # <account_name> <sex> <email> <password>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'\s+(\S+)\s+(\S+)\s+(.*)/)) {
+ createaccount($paramlist[0], $paramlist[1], $paramlist[2], $paramlist[3]); # <account_name> <sex> <email> <password>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'\s+(\S+)\s+(\S+)/)) {
+ createaccount($paramlist[0], $paramlist[1], $paramlist[2], ""); # <account_name> <sex> <email> <password>
+ } else {
+ @paramlist = split /\s+/,$parameters;
+ createaccount($paramlist[0], $paramlist[1], $paramlist[2], $paramlist[3]); # <account_name> <sex> <email> <password>
+ }
+
+ } elsif ("del" =~ /^\Q$command/ || "delete" =~ /^\Q$command/) {
+ if (@paramlist = ($parameters =~ m/^"(.*)"/)) {
+ delaccount($paramlist[0]); # <account_name>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'/)) {
+ delaccount($paramlist[0]); # <account_name>
+ } else {
+ @paramlist = split /\s+/,$parameters,1;
+ delaccount($paramlist[0]); # <account_name>
+ }
+
+ } elsif ("email" =~ /^\Q$command/ && $command ne "e") { # check 1 letter command: 'email', 'end' or 'exit'?
+ if (@paramlist = ($parameters =~ m/^"(.*)"\s+(\S+)/)) {
+ changeemail($paramlist[0], $paramlist[1]); # <account_name> <email>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'\s+(\S+)/)) {
+ changeemail($paramlist[0], $paramlist[1]); # <account_name> <email>
+ } else {
+ @paramlist = split /\s+/,$parameters;
+ changeemail($paramlist[0], $paramlist[1]); # <account_name> <email>
+ }
+
+ } elsif ("getcount" =~ /^\Q$command/ && $command ne "g") { # check 1 letter command: 'getcount' or 'gm'?
+ getlogincount();
+
+ } elsif ("gm" =~ /^\Q$command/ && $command ne "g") { # check 1 letter command: 'getcount' or 'gm'?
+ if (@paramlist = ($parameters =~ m/^"(.*)"\s+(\S+)/)) {
+ changegmlevel($paramlist[0], int($paramlist[1])); # <account_name> <GM_level>
+ } elsif (@paramlist = ($parameters =~ m/^"(.*)"/)) {
+ changegmlevel($paramlist[0], 0); # <account_name> <GM_level>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'\s+(\S+)/)) {
+ changegmlevel($paramlist[0], int($paramlist[1])); # <account_name> <GM_level>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'/)) {
+ changegmlevel($paramlist[0], 0); # <account_name> <GM_level>
+ } else {
+ @paramlist = split /\s+/,$parameters;
+ changegmlevel($paramlist[0], int($paramlist[1])); # <account_name> <GM_level>
+ }
+
+ } elsif ("id" =~ /^\Q$command/ && $command ne "i") { # check 1 letter command: 'id' or 'info'?
+ if (@paramlist = ($parameters =~ m/^"(.*)"/)) {
+ idaccount($paramlist[0]); # <account_name>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'/)) {
+ idaccount($paramlist[0]); # <account_name>
+ } else {
+ @paramlist = split /\s+/,$parameters,1;
+ idaccount($paramlist[0]); # <account_name>
+ }
+
+ } elsif ("info" =~ /^\Q$command/ && $command ne "i") { # check 1 letter command: 'id' or 'info'?
+ infoaccount(int($paramlist[0])); # <account_id>
+
+ } elsif ($command eq "kami") { # check all letters command: 'kami' or 'kamib'?
+ @paramlist = split /\s+/,$parameters,1;
+ sendbroadcast(0, $paramlist[0]); # <type> <message>
+
+ } elsif ($command eq "kamib") { # check all letters command: 'kami' or 'kamib'?
+ @paramlist = split /\s+/,$parameters,1;
+ sendbroadcast(0x10, $paramlist[0]); # <type> <message>
+
+ } elsif ("language" =~ /^\Q$command/ && $command ne "l") { # check 1 letter command: 'list' or 'language'?
+ changelanguage($paramlist[0]); # <language>
+
+ } elsif (("list" =~ /^\Q$command/ || $command eq "ls") && $command ne "l") { # check 1 letter command: 'list' or 'language'?
+ listaccount(int($paramlist[0]), int($paramlist[1]), 0); # [start_id [end_id]] 0: to list all
+
+ } elsif (("listban" =~ /^\Q$command/ || $command eq "lsban") && $command ne "l") { # need to specificaly write Ban to have this list # check 1 letter command: 'list' or 'language'?
+ listaccount(int($paramlist[0]), int($paramlist[1]), 3); # [start_id [end_id]] 3: to list only accounts with state or banished
+
+ } elsif (("listgm" =~ /^\Q$command/ || $command eq "lsgm") && $command ne "l") { # need to specificaly write GM to have this list # check 1 letter command: 'list' or 'language'?
+ listaccount(int($paramlist[0]), int($paramlist[1]), 1); # [start_id [end_id]] 1: to list only GM
+
+ } elsif (("listok" =~ /^\Q$command/ || $command eq "lsok") && $command ne "l") { # need to specificaly write OK to have this list # check 1 letter command: 'list' or 'language'?
+ listaccount(int($paramlist[0]), int($paramlist[1]), 4); # [start_id [end_id]] 4: to list only accounts without state and not banished
+
+ } elsif ("memo" =~ /^\Q$command/) {
+ if (@paramlist = ($parameters =~ m/^"(.*)"\s+(.*)/)) {
+ changememo($paramlist[0], $paramlist[1]); # <account_name> <memo>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'\s+(.*)/)) {
+ changememo($paramlist[0], $paramlist[1]); # <account_name> <memo>
+ } else {
+ @paramlist = split /\s+/,$parameters,2;
+ changememo($paramlist[0], $paramlist[1]); # <account_name> <memo>
+ }
+
+ } elsif ("name" =~ /^\Q$command/) {
+ nameaccount(int($paramlist[0])); # <account_id>
+
+ } elsif ("passwd" =~ /^\Q$command/ || "password" =~ /^\Q$command/) {
+ if (@paramlist = ($parameters =~ m/^"(.*)"\s+(.*)/)) {
+ changepasswd($paramlist[0], $paramlist[1]); # <account_name> <new_password>
+ } elsif (@paramlist = ($parameters =~ m/^"(.*)"/)) {
+ changepasswd($paramlist[0], ""); # <account_name> <new_password>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'\s+(.*)/)) {
+ changepasswd($paramlist[0], $paramlist[1]); # <account_name> <new_password>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'/)) {
+ changepasswd($paramlist[0], ""); # <account_name> <new_password>
+ } else {
+ @paramlist = split /\s+/,$parameters,2;
+ changepasswd($paramlist[0], $paramlist[1]); # <account_name> <new_password>
+ }
+
+ } elsif ("reloadgm" =~ /^\Q$command/) {
+ reloadGM();
+
+ } elsif ("search" =~ /^\Q$command/ && $command ne "s" && # check 1 letter command: 'search', 'state' or 'sex'?
+ $command ne "se") { # check 2 letters command: 'search' or 'sex'?
+ if (@paramlist = ($parameters =~ m/^(-{1,2}[re]\S*)\s+(.*)/)) {
+ searchaccount($paramlist[0], $paramlist[1]); # -r/-e/--expr/--regex <expression> | <expression>
+ } else {
+ @paramlist = split /\s+/,$parameters,1;
+ searchaccount($paramlist[0], ""); # -r/-e/--expr/--regex <expression> | <expression>
+ }
+
+ } elsif ("sex" =~ /^\Q$command/ && $command ne "s" && # check 1 letter command: 'search', 'state' or 'sex'?
+ $command ne "se") { # check 2 letters command: 'search' or 'sex'?
+ if (@paramlist = ($parameters =~ m/^"(.*)"\s+(\S+)/)) {
+ changesex($paramlist[0], $paramlist[1]); # <account_name> <sex>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'\s+(\S+)/)) {
+ changesex($paramlist[0], $paramlist[1]); # <account_name> <sex>
+ } else {
+ @paramlist = split /\s+/,$parameters;
+ changesex($paramlist[0], $paramlist[1]); # <account_name> <sex>
+ }
+
+ } elsif ("state" =~ /^\Q$command/ && $command ne "s") { # check 1 letter command: 'search', 'state' or 'sex'?
+ if (@paramlist = ($parameters =~ m/^"(.*)"\s+(\d+)\s+(.*)/)) {
+ changestate($paramlist[0], int($paramlist[1]), $paramlist[2]); # <account_name> <new_state> <error_message_#7>
+ } elsif (@paramlist = ($parameters =~ m/^"(.*)"\s+(\d+)/)) {
+ changestate($paramlist[0], int($paramlist[1]), ""); # <account_name> <new_state> <error_message_#7>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'\s+(\d+)\s+(.*)/)) {
+ changestate($paramlist[0], int($paramlist[1]), $paramlist[2]); # <account_name> <new_state> <error_message_#7>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'\s+(\d+)/)) {
+ changestate($paramlist[0], int($paramlist[1]), ""); # <account_name> <new_state> <error_message_#7>
+ } else {
+ @paramlist = split /\s+/,$parameters,3;
+ changestate($paramlist[0], int($paramlist[1]), $paramlist[2]); # <account_name> <new_state> <error_message_#7>
+ }
+
+ } elsif (("timeadd" =~ /^\Q$command/ || $command eq "ta") && $command ne "t") { # check 1 letter command: 'ta' or 'ts'?
+ if (@paramlist = ($parameters =~ m/^"(.*)"\s+(\S+)/)) {
+ timeaddaccount($paramlist[0], $paramlist[1]); # <account_name> <modifier>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'\s+(\S+)/)) {
+ timeaddaccount($paramlist[0], $paramlist[1]); # <account_name> <modifier>
+ } else {
+ @paramlist = split /\s+/,$parameters;
+ timeaddaccount($paramlist[0], $paramlist[1]); # <account_name> <modifier>
+ }
+
+ } elsif (("timeset" =~ /^\Q$command/ || $command eq "ts") && $command ne "t") { # check 1 letter command: 'ta' or 'ts'?
+ if (@paramlist = ($parameters =~ m/^"(.*)"\s+(\S+)\s+(\S+)/)) {
+ timesetaccount($paramlist[0], $paramlist[1], $paramlist[2]); # <account_name> yyyy/mm/dd [hh:mm:ss]
+ } elsif (@paramlist = ($parameters =~ m/^"(.*)"\s+(\S+)/)) {
+ timesetaccount($paramlist[0], $paramlist[1], "23:59:59"); # <account_name> yyyy/mm/dd [hh:mm:ss]
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'\s+(\S+)\s+(\S+)/)) {
+ timesetaccount($paramlist[0], $paramlist[1], $paramlist[2]); # <account_name> yyyy/mm/dd [hh:mm:ss]
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'\s+(\S+)/)) {
+ timesetaccount($paramlist[0], $paramlist[1], "23:59:59"); # <account_name> yyyy/mm/dd [hh:mm:ss]
+ } else {
+ @paramlist = split /\s+/,$parameters;
+ timesetaccount($paramlist[0], $paramlist[1], $paramlist[2]); # <account_name> yyyy/mm/dd [hh:mm:ss]
+ }
+
+ } elsif ($command eq "unban" || ("unbanish" =~ /^\Q$command/ && length($command) >= 4)) {
+ if (@paramlist = ($parameters =~ m/^"(.*)"/)) {
+ bansetaccount($paramlist[0], 0, ""); # <account_name> yyyy/mm/dd [hh:mm:ss]
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'/)) {
+ bansetaccount($paramlist[0], 0, ""); # <account_name> yyyy/mm/dd [hh:mm:ss]
+ } else {
+ @paramlist = split /\s+/,$parameters,1;
+ bansetaccount($paramlist[0], 0, ""); # <account_name> yyyy/mm/dd [hh:mm:ss]
+ }
+
+ } elsif ("unblock" =~ /^\Q$command/ && length($command) >= 4) {
+ if (@paramlist = ($parameters =~ m/^"(.*)"/)) {
+ changestate($paramlist[0], 0, ""); # <account_name> <new_state> <error_message_#7>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'/)) {
+ changestate($paramlist[0], 0, ""); # <account_name> <new_state> <error_message_#7>
+ } else {
+ @paramlist = split /\s+/,$parameters,1;
+ changestate($paramlist[0], 0, ""); # <account_name> <new_state> <error_message_#7>
+ }
+
+ } elsif ("version" =~ /^\Q$command/) {
+ checkloginversion();
+
+ } elsif ("who" =~ /^\Q$command/) {
+ if (@paramlist = ($parameters =~ m/^"(.*)"/)) {
+ whoaccount($paramlist[0]); # <account_name>
+ } elsif (@paramlist = ($parameters =~ m/^'(.*)'/)) {
+ whoaccount($paramlist[0]); # <account_name>
+ } else {
+ @paramlist = split /\s+/,$parameters,1;
+ whoaccount($paramlist[0]); # <account_name>
+ }
+
+# quit
+ } elsif ("quit" =~ /^\Q$command/ ||
+ (("end" =~ /^\Q$command/ || "exit" =~ /^\Q$command/) && $command ne "e")) { # check 1 letter command: 'email', 'end' or 'exit'?
+ last;
+
+# unknown command
+ } elsif ($command) {
+ if ($defaultlanguage eq "F") {
+ print "Commande inconnue [".$command."]\n";
+ } else {
+ print "Unknown command [".$command."]\n";
+ }
+ }
+# $term->addhistory($cmd) if $command;
+ };
+ if ($@) {
+ if ($defaultlanguage eq "F") {
+ print "Erreur [".$command."]\n$@";
+ } else {
+ print "Error [".$command."]\n$@";
+ }
+ }
+};
+
+# End of the software
+quit();
+
+if ($defaultlanguage eq "F") {
+ print "Au revoir.\n";
+} else {
+ print "Bye.\n";
+}
+exit(0);
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Displaying of the version of the login-server
+sub checkloginversion() {
+ print $so pack("v",30000); # 0x7530
+ $so->flush();
+ $buf = readso(10);
+ # Analyse du Packet
+ my($ret, $maver, $miver, $rev, $dev, $mod, $type, $mdver) = unpack("vc6v", $buf);
+ if ($ret != 30001) { #0x7531
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ exit(6);
+ }
+
+ print " Login-Server [$loginserverip:$loginserverport]\n";
+ printf " eAthena version %s-%d.%d", ("stable", "dev")[$dev], $maver, $miver;
+ printf " revision %d", $rev if $rev;
+ printf "%s%d.\n", ("", "-mod")[$mod], $mdver;
+ return 0;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Displaying of the help
+sub displayhelp() {
+ my($help, $receivedcommand) = @_;
+
+ my($command) = lc($receivedcommand); # command in lowercase
+
+ if ($command eq "") {
+ $command = "not a command"; # any value that is not a command
+ }
+
+ if ($command eq "?") {
+ $command = "aide" if ($defaultlanguage eq "F");
+ $command = "help" if ($defaultlanguage ne "F");
+ }
+
+ if ($help eq "aide") {
+ if ("aide" =~ /^\Q$command/ && $command ne "a") { # check 1 letter command: 'aide' or 'add'?
+ printf "aide/help/?\n";
+ printf " Affiche la description des commandes\n";
+ printf "aide/help/? [commande]\n";
+ printf " Affiche la description de la commande specifiée\n";
+ } elsif ("help" =~ /^\Q$command/) {
+ printf "aide/help/?\n";
+ printf " Display the description of the commands\n";
+ printf "aide/help/? [command]\n";
+ printf " Display the description of the specified command\n";
+ } elsif ("add" =~ /^\Q$command/ && $command ne "a") { # check 1 letter command: 'aide' or 'add'?
+ printf "add <nomcompte> <sexe> <motdepasse>\n";
+ printf " Crée un compte avec l'email par défaut (a\@a.com).\n";
+ printf " Concernant le sexe, seule la première lettre compte (F ou M).\n";
+ printf " L'e-mail est a\@a.com (e-mail par défaut). C'est comme n'avoir aucun e-mail.\n";
+ printf " Lorsque motdepasse est omis, la saisie se fait sans que la frappe se voit.\n";
+ printf " <exemple> add testname Male testpass\n";
+ } elsif ($command eq "ban" || ("banish" =~ /^\Q$command/ && length($command) >= 4)) {
+ printf "ban/banish aaaa/mm/jj hh:mm:ss <nomcompte>\n";
+ printf " Change la date de fin de bannissement d'un compte.\n";
+ printf " La différence avec banset est la position du nom du compte.\n";
+ } elsif (("banadd" =~ /^\Q$command/ || $command eq "ba") && $command ne "b") { # check 1 letter command: 'ba' or 'bs'?
+ printf "banadd <nomcompte> <Modificateur>\n";
+ printf " Ajoute ou soustrait du temps à la date de banissement d'un compte.\n";
+ printf " Les modificateurs sont construits comme suit:\n";
+ printf " Valeur d'ajustement (-1, 1, +1, etc...)\n";
+ printf " Elément modifié:\n";
+ printf " a ou y: année\n";
+ printf " m: mois\n";
+ printf " j ou d: jour\n";
+ printf " h: heure\n";
+ printf " mn: minute\n";
+ printf " s: seconde\n";
+ printf " <exemple> banadd testname +1m-2mn1s-6a\n";
+ printf " Cette exemple ajoute 1 mois et une seconde, et soustrait 2 minutes\n";
+ printf " et 6 ans dans le même temps.\n";
+ printf "NOTE: Si vous modifez la date de banissement d'un compte non bani,\n";
+ printf " vous indiquez comme date (le moment actuel +- les ajustements)\n";
+ } elsif (("banset" =~ /^\Q$command/ || $command eq "bs") && $command ne "b") { # check 1 letter command: 'ba' or 'bs'?
+ printf "banset <nomcompte> aaaa/mm/jj [hh:mm:ss]\n";
+ printf " Change la date de fin de bannissement d'un compte.\n";
+ printf " Heure par défaut: 23:59:59\n";
+ printf "banset <nomcompte> 0\n";
+ printf " Débanni un compte (0 = de-banni).\n";
+ } elsif ("block" =~ /^\Q$command/ && length($command) >= 2) {
+ printf "block <nom compte>\n";
+ printf " Place le status d'un compte à 5 (You have been blocked by the GM Team).\n";
+ printf " La commande est l'équivalent de state <nom_compte> 5.\n";
+ } elsif ("check" =~ /^\Q$command/ && $command ne "c") { # check 1 letter command: 'check' or 'create'?
+ printf "check <nomcompte> <motdepasse>\n";
+ printf " Vérifie la validité d'un mot de passe pour un compte\n";
+ printf " NOTE: Le serveur n'enverra jamais un mot de passe.\n";
+ printf " C'est la seule méthode que vous possédez pour savoir\n";
+ printf " si un mot de passe est le bon. L'autre méthode est\n";
+ printf " d'avoir un accès ('physique') au fichier des comptes.\n";
+ } elsif ("create" =~ /^\Q$command/ && $command ne "c") { # check 1 letter command: 'check' or 'create'?
+ printf "create <nomcompte> <sexe> <email> <motdepasse>\n";
+ printf " Comme la commande add, mais avec l'e-mail en plus.\n";
+ printf " <exemple> create testname Male mon\@mail.com testpass\n";
+ } elsif ("del" =~ /^\Q$command/ || "delete" =~ /^\Q$command/) {
+ printf "del <nomcompte>\n";
+ printf " Supprime un compte.\n";
+ printf " La commande demande confirmation. Après confirmation, le compte est détruit.\n";
+ } elsif ("email" =~ /^\Q$command/ && $command ne "e") { # check 1 letter command: 'email', 'end' or 'exit'?
+ printf "email <nomcompte> <email>\n";
+ printf " Modifie l'e-mail d'un compte.\n";
+ } elsif ("getcount" =~ /^\Q$command/ && $command ne "g") { # check 1 letter command: 'getcount' or 'gm'?
+ printf "getcount\n";
+ printf " Donne le nombre de joueurs en ligne par serveur de char.\n";
+ } elsif ("gm" =~ /^\Q$command/ && $command ne "g") { # check 1 letter command: 'getcount' or 'gm'?
+ printf "gm <nomcompte> [Niveau_GM]\n";
+ printf " Modifie le niveau de GM d'un compte.\n";
+ printf " Valeur par défaut: 0 (suppression du niveau de GM).\n";
+ printf " <exemple> gm nomtest 80\n";
+ } elsif ("id" =~ /^\Q$command/ && $command ne "i") { # check 1 letter command: 'id' or 'info'?
+ printf "id <nomcompte>\n";
+ printf " Donne l'id d'un compte.\n";
+ } elsif ("info" =~ /^\Q$command/ && $command ne "i") { # check 1 letter command: 'id' or 'info'?
+ printf "info <idcompte>\n";
+ printf " Affiche les informations sur un compte.\n";
+ } elsif ($command eq "kami") { # check all letters command: 'kami' or 'kamib'?
+ printf "kami <message>\n";
+ printf " Envoi un message général sur tous les serveurs de map (en jaune).\n";
+ } elsif ($command eq "kamib") { # check all letters command: 'kami' or 'kamib'?
+ printf "kamib <message>\n";
+ printf " Envoi un message général sur tous les serveurs de map (en bleu).\n";
+ } elsif ("language" =~ /^\Q$command/ && $command ne "l") { # check 1 letter command: 'list' or 'language'?
+ printf("language <langue>\n");
+ printf(" Change la langue d'affichage.\n");
+ printf(" Langues possibles: 'Français' ou 'English'.\n");
+ } elsif (("list" =~ /^\Q$command/ || $command eq "ls") && $command ne "l") { # check 1 letter command: 'list' or 'language'?
+ printf "list/ls [Premier_id [Dernier_id]]\n";
+ printf " Affiche une liste de comptes.\n";
+ printf " 'Premier_id', 'Dernier_id': indique les identifiants de départ et de fin.\n";
+ printf " La recherche par nom n'est pas possible avec cette commande.\n";
+ printf " <example> list 10 9999999\n";
+ } elsif (("listban" =~ /^\Q$command/ || $command eq "lsban") && $command ne "l") { # need to specificaly write Ban to have this list # check 1 letter command: 'list' or 'language'?
+ printf "listBan/lsBan [Premier_id [Dernier_id]]\n";
+ printf " Comme list/ls, mais seulement pour les comptes GM avec un statut ou bannis.\n";
+ } elsif (("listgm" =~ /^\Q$command/ || $command eq "lsgm") && $command ne "l") { # need to specificaly write GM to have this list # check 1 letter command: 'list' or 'language'?
+ printf "listGM/lsGM [Premier_id [Dernier_id]]\n";
+ printf " Comme list/ls, mais seulement pour les comptes GM.\n";
+ } elsif (("listok" =~ /^\Q$command/ || $command eq "lsok") && $command ne "l") { # need to specificaly write OK to have this list # check 1 letter command: 'list' or 'language'?
+ printf "listOK/lsOK [Premier_id [Dernier_id]]\n";
+ printf " Comme list/ls, mais seulement pour les comptes sans statut et non bannis.\n";
+ } elsif ("memo" =~ /^\Q$command/) {
+ printf "memo <nomcompte> <memo>\n";
+ printf " Modifie le mémo d'un compte.\n";
+ printf " 'memo': Il peut avoir jusqu'à 253 caractères (avec des espaces ou non).\n";
+ } elsif ("name" =~ /^\Q$command/) {
+ printf "name <idcompte>\n";
+ printf " Donne le nom d'un compte.\n";
+ } elsif ("passwd" =~ /^\Q$command/ || "password" =~ /^\Q$command/) {
+ printf "passwd <nomcompte> <nouveaumotdepasse>\n";
+ printf " Change le mot de passe d'un compte.\n";
+ printf " Lorsque nouveaumotdepasse est omis,\n";
+ printf " la saisie se fait sans que la frappe ne se voit.\n";
+ } elsif ("reloadgm" =~ /^\Q$command/) {
+ printf "reloadGM\n";
+ printf " Reload GM configuration file\n";
+ } elsif ("search" =~ /^\Q$command/ && $command ne "s" && # check 1 letter command: 'search', 'state' or 'sex'?
+ $command ne "se") { # check 2 letters command: 'search' or 'sex'?
+ printf "search <expression>\n";
+ printf " Cherche des comptes.\n";
+ printf " Affiche les comptes dont les noms correspondent.\n";
+ printf "search -r/-e/--expr/--regex <expression>\n";
+ printf " Cherche des comptes par expression regulière.\n";
+ printf " Affiche les comptes dont les noms correspondent.\n";
+ } elsif ("sex" =~ /^\Q$command/ && $command ne "s" && # check 1 letter command: 'search', 'state' or 'sex'?
+ $command ne "se") { # check 2 letters command: 'search' or 'sex'?
+ printf "sex <nomcompte> <sexe>\n";
+ printf " Modifie le sexe d'un compte.\n";
+ printf " <exemple> sex testname Male\n";
+ } elsif ("state" =~ /^\Q$command/ && $command ne "s") { # check 1 letter command: 'search', 'state' or 'sex'?
+ printf "state <nomcompte> <nouveaustatut> <message_erreur_7>\n";
+ printf " Change le statut d'un compte.\n";
+ printf " 'nouveaustatut': Le statut est le même que celui du packet 0x006a + 1.\n";
+ printf " les possibilités sont:\n";
+ printf " 0 = Compte ok\n";
+ printf " 1 = Unregistered ID\n";
+ printf " 2 = Incorrect Password\n";
+ printf " 3 = This ID is expired\n";
+ printf " 4 = Rejected from Server\n";
+ printf " 5 = You have been blocked by the GM Team\n";
+ printf " 6 = Your Game's EXE file is not the latest version\n";
+ printf " 7 = You are Prohibited to log in until...\n";
+ printf " 8 = Server is jammed due to over populated\n";
+ printf " 9 = No MSG\n";
+ printf " 100 = This ID has been totally erased\n";
+ printf " all other values are 'No MSG', then use state 9 please.\n";
+ printf " 'message_erreur_7': message du code erreur 6 =\n";
+ printf " = Your are Prohibited to log in until... (packet 0x006a)\n";
+ } elsif (("timeadd" =~ /^\Q$command/ || $command eq "ta") && $command ne "t") { # check 1 letter command: 'ta' or 'ts'?
+ printf "timeadd <nomcompte> <modificateur>\n";
+ printf " Ajoute/soustrait du temps à la limite de validité d'un compte.\n";
+ printf " Le modificateur est composé comme suit:\n";
+ printf " Valeur modificatrice (-1, 1, +1, etc...)\n";
+ printf " Elément modifié:\n";
+ printf " a ou y: année\n";
+ printf " m: mois\n";
+ printf " j ou d: jour\n";
+ printf " h: heure\n";
+ printf " mn: minute\n";
+ printf " s: seconde\n";
+ printf " <exemple> timeadd testname +1m-2mn1s-6a\n";
+ printf " Cette exemple ajoute 1 mois et une seconde, et soustrait 2 minutes\n";
+ printf " et 6 ans dans le même temps.\n";
+ printf "NOTE: Vous ne pouvez pas modifier une limite de validité illimitée. Si vous\n";
+ printf " désirez le faire, c'est que vous voulez probablement créer un limite de\n";
+ printf " validité limitée. Donc, en premier, fixé une limite de valitidé.\n";
+ } elsif (("timeset" =~ /^\Q$command/ || $command eq "ts") && $command ne "t") { # check 1 letter command: 'ta' or 'ts'?
+ printf "timeset <nomcompte> aaaa/mm/jj [hh:mm:ss]\n";
+ printf " Change la limite de validité d'un compte.\n";
+ printf " Heure par défaut: 23:59:59\n";
+ printf "timeset <nomcompte> 0\n";
+ printf " Donne une limite de validité illimitée (0 = illimitée).\n";
+ } elsif ($command eq "unban" || ("unbanish" =~ /^\Q$command/ && length($command) >= 4)) {
+ printf "unban/unbanish <nom compte>\n";
+ printf " Ote le banissement d'un compte.\n";
+ printf " La commande est l'équivalent de banset <nom_compte> 0.\n";
+ } elsif ("unblock" =~ /^\Q$command/ && length($command) >= 4) {
+ printf "unblock <nom compte>\n";
+ printf " Place le status d'un compte à 0 (Compte ok).\n";
+ printf " La commande est l'équivalent de state <nom_compte> 0.\n";
+ } elsif ("version" =~ /^\Q$command/) {
+ printf "version\n";
+ printf " Affiche la version du login-serveur.\n";
+ } elsif ("who" =~ /^\Q$command/) {
+ printf "who <nomcompte>\n";
+ printf " Affiche les informations sur un compte.\n";
+ } elsif ("quit" =~ /^\Q$command/ ||
+ (("end" =~ /^\Q$command/ || "exit" =~ /^\Q$command/) && $command ne "e")) { # check 1 letter command: 'email', 'end' or 'exit'?\n";
+ printf "quit/end/exit\n";
+ printf " Fin du programme d'administration.\n";
+ } else {
+ if ($receivedcommand ne "") {
+ printf "Commande inconnue [%s] pour l'aide. Affichage de toutes les commandes.\n", $receivedcommand;
+ }
+ print << "ENDOFAIDE";
+ aide/help/? -- Affiche cet aide
+ aide/help/? [commande] -- Affiche l'aide de la commande
+ add <nomcompte> <sexe> <motdepasse> -- Crée un compte (sans email)
+ ban/banish aaaa/mm/jj hh:mm:ss <nomcompte>-- Change la date finale de banismnt
+ banadd/ba <nomcompte> <modificateur> -- Ajout/soustrait du temps à la
+ exemple: ba moncompte +1m-2mn1s-2y date finale de banissement
+ banset/bs <nomcompte> aaaa/mm/jj [hh:mm:ss] -- Change la date fin de banisemnt
+ banset/bs <nomcompte> 0 -- Dé-banis un compte.
+ block <nom compte> -- Mets le status d'un compte à 5 (blocked by the GM Team)
+ check <nomcompte> <motdepasse> -- Vérifie un mot de passe d'un compte
+ create <nomcompte> <sexe> <email> <motdepasse> -- Crée un compte (avec email)
+ del <nomcompte> -- Supprime un compte
+ email <nomcompte> <email> -- Modifie l'e-mail d'un compte
+ getcount -- Donne le nb de joueurs en ligne
+ gm <nomcompte> [Niveau_GM] -- Modifie le niveau de GM d'un compte
+ id <nomcompte> -- Donne l'id d'un compte
+ info <idcompte> -- Affiche les infos sur un compte
+ kami <message> -- Envoi un message général (en jaune)
+ kamib <message> -- Envoi un message général (en bleu)
+ language <langue> -- Change la langue d'affichage.
+ list/ls [Premier_id [Dernier_id] ] -- Affiche une liste de comptes
+ listBan/lsBan [Premier_id [Dernier_id] ]-- Affiche une liste de comptes
+ avec un statut ou bannis
+ listGM/lsGM [Premier_id [Dernier_id] ] -- Affiche une liste de comptes GM
+ listOK/lsOK [Premier_id [Dernier_id] ] -- Affiche une liste de comptes
+ sans status et non bannis
+ memo <nomcompte> <memo> -- Modifie le memo d'un compte
+ name <idcompte> -- Donne le nom d'un compte
+ passwd <nomcompte> <nouveaumotdepasse> -- Change le mot de passe d'un compte
+ quit/end/exit -- Fin du programme d'administation
+ reloadGM -- Recharger le fichier de config des GM
+ search <expression> -- Cherche des comptes
+ search -e/-r/--expr/--regex <expression> -- Cherche des comptes par REGEX
+ sex <nomcompte> <sexe> -- Modifie le sexe d'un compte
+ state <nomcompte> <nouveaustatut> <messageerr7> -- Change le statut d'1 compte
+ timeadd/ta <nomcompte> <modificateur> -- Ajout/soustrait du temps à la
+ exemple: ta moncompte +1m-2mn1s-2y limite de validité
+ timeset/ts <nomcompte> aaaa/mm/jj [hh:mm:ss] -- Change la limite de validité
+ timeset/ts <nomcompte> 0 -- limite de validité = illimitée
+ unban/unbanish <nom compte> -- Ote le banissement d'un compte
+ unblock <nom compte> -- Mets le status d'un compte à 0 (Compte ok)
+ version -- Donne la version du login-serveur
+ who <nomcompte> -- Affiche les infos sur un compte
+ENDOFAIDE
+ printf(" Note: Pour les noms de compte avec des espaces, tapez \"<nom compte>\" (ou ').\n");
+ }
+ } else {
+ if ("aide" =~ /^\Q$command/ && $command ne "a") { # check 1 letter command: 'aide' or 'add'?
+ printf "aide/help/?\n";
+ printf " Display the description of the commands\n";
+ printf "aide/help/? [command]\n";
+ printf " Display the description of the specified command\n";
+ } elsif ("help" =~ /^\Q$command/) {
+ printf "aide/help/?\n";
+ printf " Display the description of the commands\n";
+ printf "aide/help/? [command]\n";
+ printf " Display the description of the specified command\n";
+ } elsif ("add" =~ /^\Q$command/ && $command ne "a") { # check 1 letter command: 'aide' or 'add'?
+ printf "add <account_name> <sex> <password>\n";
+ printf " Create an account with the default email (a\@a.com).\n";
+ printf " Concerning the sex, only the first letter is used (F or M).\n";
+ printf " The e-mail is set to a\@a.com (default e-mail). It's like to have no e-mail.\n";
+ printf " When the password is omitted,\n";
+ printf " the input is done without displaying of the pressed keys.\n";
+ printf " <example> add testname Male testpass\n";
+ } elsif ($command eq "ban" || ("banish" =~ /^\Q$command/ && length($command) >= 4)) {
+ printf "ban/banish yyyy/mm/dd hh:mm:ss <account_name>\n";
+ printf " Changes the final date of a banishment of an account.\n";
+ printf " The difference with banset is the position of the account name.\n";
+ } elsif (("banadd" =~ /^\Q$command/ || $command eq "ba") && $command ne "b") { # check 1 letter command: 'ba' or 'bs'?
+ printf "banadd <account_name> <modifier>\n";
+ printf " Adds or substracts time from the final date of a banishment of an account.\n";
+ printf " Modifier is done as follows:\n";
+ printf " Adjustment value (-1, 1, +1, etc...)\n";
+ printf " Modified element:\n";
+ printf " a or y: year\n";
+ printf " m: month\n";
+ printf " j or d: day\n";
+ printf " h: hour\n";
+ printf " mn: minute\n";
+ printf " s: second\n";
+ printf " <example> banadd testname +1m-2mn1s-6y\n";
+ printf " this example adds 1 month and 1 second, and substracts 2 minutes\n";
+ printf " and 6 years at the same time.\n";
+ printf "NOTE: If you modify the final date of a non-banished account,\n";
+ printf " you fix the final date to (actual time +- adjustments)\n";
+ } elsif (("banset" =~ /^\Q$command/ || $command eq "bs") && $command ne "b") { # check 1 letter command: 'ba' or 'bs'?
+ printf "banset <account_name> yyyy/mm/dd [hh:mm:ss]\n";
+ printf " Changes the final date of a banishment of an account.\n";
+ printf " Default time: 23:59:59\n";
+ printf "banset <account_name> 0\n";
+ printf " Set a non-banished account (0 = unbanished).\n";
+ } elsif ("block" =~ /^\Q$command/ && length($command) >= 2) {
+ printf "block <account name>\n";
+ printf " Set state 5 (You have been blocked by the GM Team) to an account.\n";
+ printf " Same command of state <account_name> 5.\n";
+ } elsif ("check" =~ /^\Q$command/ && $command ne "c") { # check 1 letter command: 'check' or 'create'?
+ printf "check <account_name> <password>\n";
+ printf " Check the validity of a password for an account.\n";
+ printf " NOTE: Server will never sends back a password.\n";
+ printf " It's the only method you have to know if a password is correct.\n";
+ printf " The other method is to have a ('physical') access to the accounts file.\n";
+ } elsif ("create" =~ /^\Q$command/ && $command ne "c") { # check 1 letter command: 'check' or 'create'?
+ printf "create <account_name> <sex> <email> <password>\n";
+ printf " Like the 'add' command, but with e-mail moreover.\n";
+ printf " <example> create testname Male my\@mail.com testpass\n";
+ } elsif ("del" =~ /^\Q$command/ || "delete" =~ /^\Q$command/) {
+ printf "del <account_name>\n";
+ printf " Remove an account.\n";
+ printf " This order requires confirmation. After confirmation, the account is deleted.\n";
+ } elsif ("email" =~ /^\Q$command/ && $command ne "e") { # check 1 letter command: 'email', 'end' or 'exit'?
+ printf "email <account_name> <email>\n";
+ printf " Modify the e-mail of an account.\n";
+ } elsif ("getcount" =~ /^\Q$command/ && $command ne "g") { # check 1 letter command: 'getcount' or 'gm'?
+ printf "getcount\n";
+ printf " Give the number of players online on all char-servers.\n";
+ } elsif ("gm" =~ /^\Q$command/ && $command ne "g") { # check 1 letter command: 'getcount' or 'gm'?
+ printf "gm <account_name> [GM_level]\n";
+ printf " Modify the GM level of an account.\n";
+ printf " Default value remove GM level (GM level = 0).\n";
+ printf " <example> gm testname 80\n";
+ } elsif ("id" =~ /^\Q$command/ && $command ne "i") { # check 1 letter command: 'id' or 'info'?
+ printf "id <account_name>\n";
+ printf " Give the id of an account.\n";
+ } elsif ("info" =~ /^\Q$command/ && $command ne "i") { # check 1 letter command: 'id' or 'info'?
+ printf "info <account_id>\n";
+ printf " Display complete information of an account.\n";
+ } elsif ($command eq "kami") { # check all letters command: 'kami' or 'kamib'?
+ printf "kami <message>\n";
+ printf " Sends a broadcast message on all map-server (in yellow).\n";
+ } elsif ($command eq "kamib") { # check all letters command: 'kami' or 'kamib'?
+ printf "kamib <message>\n";
+ printf " Sends a broadcast message on all map-server (in blue).\n";
+ } elsif ("language" =~ /^\Q$command/ && $command ne "l") { # check 1 letter command: 'list' or 'language'?
+ printf("language <language>\n");
+ printf(" Change the language of displaying.\n");
+ printf(" Possible languages: Français or English.\n");
+ } elsif (("list" =~ /^\Q$command/ || $command eq "ls") && $command ne "l") { # check 1 letter command: 'list' or 'language'?
+ printf "list/ls [start_id [end_id]]\n";
+ printf " Display a list of accounts.\n";
+ printf " 'start_id', 'end_id': indicate end and start identifiers.\n";
+ printf " Research by name is not possible with this command.\n";
+ printf " <example> list 10 9999999\n";
+ } elsif (("listban" =~ /^\Q$command/ || $command eq "lsban") && $command ne "l") { # need to specificaly write Ban to have this list # check 1 letter command: 'list' or 'language'?
+ printf "listBan/lsBan [start_id [end_id]]\n";
+ printf " Like list/ls, but only for accounts with state or banished.\n";
+ } elsif (("listgm" =~ /^\Q$command/ || $command eq "lsgm") && $command ne "l") { # need to specificaly write GM to have this list # check 1 letter command: 'list' or 'language'?
+ printf "listGM/lsGM [start_id [end_id]]\n";
+ printf " Like list/ls, but only for GM accounts.\n";
+ } elsif (("listok" =~ /^\Q$command/ || $command eq "lsok") && $command ne "l") { # need to specificaly write OK to have this list # check 1 letter command: 'list' or 'language'?
+ printf "listOK/lsOK [start_id [end_id]]\n";
+ printf " Like list/ls, but only for accounts without state and not banished.\n";
+ } elsif ("memo" =~ /^\Q$command/) {
+ printf "memo <account_name> <memo>\n";
+ printf " Modify the memo of an account.\n";
+ printf " 'memo': it can have until 253 characters (with spaces or not).\n";
+ } elsif ("name" =~ /^\Q$command/) {
+ printf "name <account_id>\n";
+ printf " Give the name of an account.\n";
+ } elsif ("passwd" =~ /^\Q$command/ || "password" =~ /^\Q$command/) {
+ printf "passwd <account_name> <new_password>\n";
+ printf " Change the password of an account.\n";
+ printf " When new password is omitted,\n";
+ printf " the input is done without displaying of the pressed keys.\n";
+ } elsif ("reloadgm" =~ /^\Q$command/) {
+ printf "reloadGM\n";
+ printf " Reload GM configuration file\n";
+ } elsif ("search" =~ /^\Q$command/ && $command ne "s" && # check 1 letter command: 'search', 'state' or 'sex'?
+ $command ne "se") { # check 2 letters command: 'search' or 'sex'?
+ printf "search <expression>\n";
+ printf " Seek accounts.\n";
+ printf " Displays the accounts whose names correspond.\n";
+ printf "search -r/-e/--expr/--regex <expression>\n";
+ printf " Seek accounts by regular expression.\n";
+ printf " Displays the accounts whose names correspond.\n";
+ } elsif ("sex" =~ /^\Q$command/ && $command ne "s" && # check 1 letter command: 'search', 'state' or 'sex'?
+ $command ne "se") { # check 2 letters command: 'search' or 'sex'?
+ printf "sex <account_name> <sex>\n";
+ printf " Modify the sex of an account.\n";
+ printf " <example> sex testname Male\n";
+ } elsif ("state" =~ /^\Q$command/ && $command ne "s") { # check 1 letter command: 'search', 'state' or 'sex'?
+ printf "state <account_name> <new_state> <error_message_#7>\n";
+ printf " Change the state of an account.\n";
+ printf " 'new_state': state is the state of the packet 0x006a + 1.\n";
+ printf " The possibilities are:\n";
+ printf " 0 = Account ok\n";
+ printf " 1 = Unregistered ID\n";
+ printf " 2 = Incorrect Password\n";
+ printf " 3 = This ID is expired\n";
+ printf " 4 = Rejected from Server\n";
+ printf " 5 = You have been blocked by the GM Team\n";
+ printf " 6 = Your Game's EXE file is not the latest version\n";
+ printf " 7 = You are Prohibited to log in until...\n";
+ printf " 8 = Server is jammed due to over populated\n";
+ printf " 9 = No MSG\n";
+ printf " 100 = This ID has been totally erased\n";
+ printf " all other values are 'No MSG', then use state 9 please.\n";
+ printf " 'error_message_#7': message of the code error 6\n";
+ printf " = Your are Prohibited to log in until... (packet 0x006a)\n";
+ } elsif (("timeadd" =~ /^\Q$command/ || $command eq "ta") && $command ne "t") { # check 1 letter command: 'ta' or 'ts'?
+ printf "timeadd <account_name> <modifier>\n";
+ printf " Adds or substracts time from the validity limit of an account.\n";
+ printf " Modifier is done as follows:\n";
+ printf " Adjustment value (-1, 1, +1, etc...)\n";
+ printf " Modified element:\n";
+ printf " a or y: year\n";
+ printf " m: month\n";
+ printf " j or d: day\n";
+ printf " h: hour\n";
+ printf " mn: minute\n";
+ printf " s: second\n";
+ printf " <example> timeadd testname +1m-2mn1s-6y\n";
+ printf " this example adds 1 month and 1 second, and substracts 2 minutes\n";
+ printf " and 6 years at the same time.\n";
+ printf "NOTE: You can not modify a unlimited validity limit.\n";
+ printf " If you want modify it, you want probably create a limited validity limit.\n";
+ printf " So, at first, you must set the validity limit to a date/time.\n";
+ } elsif (("timeset" =~ /^\Q$command/ || $command eq "ts") && $command ne "t") { # check 1 letter command: 'ta' or 'ts'?
+ printf "timeset <account_name> yyyy/mm/dd [hh:mm:ss]\n";
+ printf " Changes the validity limit of an account.\n";
+ printf " Default time: 23:59:59\n";
+ printf "timeset <account_name> 0\n";
+ printf " Gives an unlimited validity limit (0 = unlimited).\n";
+ } elsif ($command eq "unban" || ("unbanish" =~ /^\Q$command/ && length($command) >= 4)) {
+ printf "unban/unbanish <account name>\n";
+ printf " Remove the banishment of an account.\n";
+ printf " This command works like banset <account_name> 0.\n";
+ } elsif ("unblock" =~ /^\Q$command/ && length($command) >= 4) {
+ printf "unblock <account name>\n";
+ printf " Set state 0 (Account ok) to an account.\n";
+ printf " This command works like state <account_name> 0.\n";
+ } elsif ("version" =~ /^\Q$command/) {
+ printf "version\n";
+ printf " Display the version of the login-server.\n";
+ } elsif ("who" =~ /^\Q$command/) {
+ printf "who <account_name>\n";
+ printf " Displays complete information of an account.\n";
+ } elsif ("quit" =~ /^\Q$command/ ||
+ (("end" =~ /^\Q$command/ || "exit" =~ /^\Q$command/) && $command ne "e")) { # check 1 letter command: 'email', 'end' or 'exit'?\n";
+ printf "quit/end/exit\n";
+ printf " End of the program of administration.\n";
+ } else {
+ if ($receivedcommand ne "") {
+ printf "Unknown command [%s] for help. Displaying of all commands.\n", $receivedcommand;
+ }
+ print << "ENDOFHELP";
+ aide/help/? -- Display this help
+ aide/help/? [command] -- Display the help of the command
+ add <account_name> <sex> <password> -- Create an account with default email
+ ban/banish yyyy/mm/dd hh:mm:ss <account_name> -- Change final date of a ban
+ banadd/ba <account_name> <modifier> -- Add or substract time from the final
+ example: ba apple +1m-2mn1s-2y date of a banishment of an account
+ banset/bs <account_name> yyyy/mm/dd [hh:mm:ss] -- Change final date of a ban
+ banset/bs <account_name> 0 -- Un-banish an account
+ block <account name> -- Set state 5 (blocked by the GM Team) to an account
+ check <account_name> <password> -- Check the validity of a password
+ create <account_name> <sex> <email> <passwrd> -- Create an account with email
+ del <account_name> -- Remove an account
+ email <account_name> <email> -- Modify an email of an account
+ getcount -- Give the number of players online
+ gm <account_name> [GM_level] -- Modify the GM level of an account
+ id <account_name> -- Give the id of an account
+ info <account_id> -- Display all information of an account
+ kami <message> -- Sends a broadcast message (in yellow)
+ kamib <message> -- Sends a broadcast message (in blue)
+ language <language> -- Change the language of displaying.
+ list/ls [First_id [Last_id]] -- Display a list of accounts
+ listBan/lsBan [First_id [Last_id]] -- Display a list of accounts
+ with state or banished
+ listGM/lsGM [First_id [Last_id]] -- Display a list of GM accounts
+ listOK/lsOK [First_id [Last_id]] -- Display a list of accounts
+ without state and not banished
+ memo <account_name> <memo> -- Modify the memo of an account
+ name <account_id> -- Give the name of an account
+ passwd <account_name> <new_password> -- Change the password of an account
+ quit/end/exit -- End of the program of administation
+ reloadGM -- Reload GM configuration file
+ search <expression> -- Seek accounts
+ search -e/-r/--expr/--regex <expressn> -- Seek accounts by regular-expression
+ sex <nomcompte> <sexe> -- Modify the sex of an account
+ state <account_name> <new_state> <error_message_#7> -- Change the state
+ timeadd/ta <account_name> <modifier> -- Add or substract time from the
+ example: ta apple +1m-2mn1s-2y validity limit of an account
+ timeset/ts <account_name> yyyy/mm/dd [hh:mm:ss] -- Change the validify limit
+ timeset/ts <account_name> 0 -- Give a unlimited validity limit
+ unban/unbanish <account name> -- Remove the banishment of an account
+ unblock <account name> -- Set state 0 (Account ok) to an account
+ version -- Gives the version of the login-server
+ who <account_name> -- Display all information of an account
+ENDOFHELP
+ printf(" Note: To use spaces in an account name, type \"<account name>\" (or ').\n");
+ }
+ }
+
+ return 0;
+}
+#--------------------------------------------------------------------------
+
+# Sub-function: Displaying of the accounts list
+sub listaccount() {
+ my($st, $ed, $listflag) = @_;
+ my($i);
+ my($n) = (0);
+ # 0123456789 01 01234567890123456789012301234 012345 0123456789012345678901234567
+ if ($defaultlanguage eq "F") {
+ print " id_compte GM nom_utilisateur sexe count statut\n";
+ } else {
+ print "account_id GM user_name sex count state\n";
+ }
+ print "-------------------------------------------------------------------------------\n";
+ while(1) {
+ print $so pack("vV2", 0x7920, $st, $ed);
+ $so->flush();
+ $buf = readso(4);
+ if (unpack("v", $buf) != 0x7921) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ exit(10);
+ }
+ my($len) = unpack("x2v", $buf);
+ last if ($len <= 4);
+ for($i = 4; $i < $len; $i += 38) {
+ my(@dat) = unpack("VCa24cVV", readso(38));
+ $st = $dat[0] + 1;
+ if ($listflag == 0 ||
+ ($listflag == 1 && $dat[1] > 0) || # check GM flag
+ ($listflag == 3 && $dat[5] != 0) || # check with state or banished
+ ($listflag == 4 && $dat[5] == 0)) { # check without state and not banished
+ printf "%10d %2s %-24s%-5s %6d %-27s\n", $dat[0],
+ ($dat[1] == 0 ? " " : $dat[1]),
+ $dat[2],
+ ($defaultlanguage eq "F" ? ("Femme","Male","Servr")[$dat[3]] : ("Femal","Male","Servr")[$dat[3]]),
+ $dat[4],
+ (($defaultlanguage eq "F" ? "Compte Ok" : "Account OK"),
+ "Unregistered ID",
+ "Incorrect Password",
+ "This ID is expired",
+ "Rejected from Server",
+ "Blocked by the GM Team", # You have been blocked by the GM Team
+ "Your EXE file is too old", # Your Game's EXE file is not the latest version
+ "Banishement or\n Prohibited to login until %s", # You are Prohibited to log in until %s
+ "Server is over populated", # Server is jammed due to over populated
+ "No MSG",
+ "This ID is totally erased")[$dat[5] == 100 ? 10 : $dat[5]]; # This ID has been totally erased
+ $n++;
+ }
+ }
+ }
+ if ($defaultlanguage eq "F") {
+ if ($n == 0) {
+ print "Aucun compte trouvé.\n";
+ } elsif ($n == 1) {
+ print "1 compte trouvé.\n";
+ } else {
+ print "$n comptes trouvés.\n";
+ }
+ } else {
+ if ($n == 0) {
+ print "No account found.\n";
+ } elsif ($n == 1) {
+ print "1 account found.\n";
+ } else {
+ print "$n accounts found.\n";
+ }
+ }
+ return 0;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: add an account with the default e-mail
+sub addaccount() {
+ my($userid, $sex, $passwd) = @_;
+ if ($userid eq "" || !defined($userid)) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un nom de compte svp.\n";
+ print "<exemple> add nomtest Male motdepassetest\n";
+ } else {
+ print "Please input an account name.\n";
+ print "<example> add testname Male testpass\n";
+ }
+ return 136;
+ }
+ if (verify_accountname($userid) == 0) {
+ return 102;
+ }
+# if ($userid =~ /[^A-Za-z0-9\@-_]/) {
+# if ($defaultlanguage eq "F") {
+# print "Caractère interdit trouvé dans le nom du compte ".$`."[${&}]${'}\n";
+# } else {
+# print "Illegal character found in the account name ".$`."[${&}]${'}\n";
+# }
+# return 101;
+# }
+ $sex = uc(substr($sex, 0, 1));
+ if ($sex !~ /^[MF]$/) {
+ if ($defaultlanguage eq "F") {
+ print "Sexe incorrect [$sex]. Entrez M ou F svp.\n";
+ } else {
+ print "Illegal gender [$sex]. Please input M or F.\n";
+ }
+ return 103;
+ }
+ if ($passwd eq "") {
+ return 108 if (($passwd = typepasswd()) eq "");
+ }
+ if (verify_password($passwd) == 0) {
+ return 104;
+ }
+ print $so pack("va24a24a1a40", 0x7930, $userid, $passwd, $sex, "");
+ $so->flush();
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x7931) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 106;
+ }
+ $buf = readso(28);
+ if (unpack("V", $buf) == -1 || unpack("V", $buf) == 4294967295) {
+ if ($defaultlanguage eq "F") {
+ print "Echec à la création du compte [$userid]. Un compte identique existe déjà.\n";
+ } else {
+ print "Account [$userid] creation failed. Same account already exists.\n";
+ }
+ return 107;
+ } else {
+ if ($defaultlanguage eq "F") {
+ printf "Compte [$userid] créé avec succès [id: %d].\n", unpack("V",$buf);
+ } else {
+ printf "Account [$userid] is successfully created [id: %d].\n", unpack("V",$buf);
+ }
+ }
+ return 0;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: add an account with an e-mail
+sub createaccount() {
+ my($userid, $sex, $email, $passwd) = @_;
+ if ($userid eq "") {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un nom de compte svp.\n";
+ print "<exemple> create nomtest Male mon\@email.com motdepassetest\n";
+ } else {
+ print "Please input an account name.\n";
+ print "<example> create testname Male my\@mail.com testpass\n";
+ }
+ return 136;
+ }
+ if (verify_accountname($userid) == 0) {
+ return 102;
+ }
+# if ($userid =~ /[^A-Za-z0-9\@-_]/) {
+# if ($defaultlanguage eq "F") {
+# print "Caractère interdit trouvé dans le nom du compte ".$`."[${&}]${'}\n";
+# } else {
+# print "Illegal character found in the account name ".$`."[${&}]${'}\n";
+# }
+# return 101;
+# }
+ $sex = uc(substr($sex, 0, 1));
+ if ($sex !~ /^[MF]$/) {
+ if ($defaultlanguage eq "F") {
+ print "Sexe incorrect [$sex]. Entrez M ou F svp.\n";
+ } else {
+ print "Illegal gender [$sex]. Please input M or F.\n";
+ }
+ return 103;
+ }
+ if (length($email) < 3) {
+ if ($defaultlanguage eq "F") {
+ print "Email trop courte [$email]. Entrez une e-mail valide svp.\n";
+ } else {
+ print "Email is too short [$email]. Please input a valid e-mail.\n";
+ }
+ return 109;
+ }
+ if (length($email) > 39) {
+ if ($defaultlanguage eq "F") {
+ print "Email trop longue [$email]. Entrez une e-mail de 39 caractères maximum svp.\n";
+ } else {
+ print "Email is too long [$email]. Please input an e-mail with 39 bytes at the most.\n";
+ }
+ return 109;
+ }
+ if (verify_email($email) == 0) {
+ if ($defaultlanguage eq "F") {
+ print "Email incorrecte [$email]. Entrez une e-mail valide svp.\n";
+ } else {
+ print "Invalid email [$email]. Please input a valid e-mail.\n";
+ }
+ return 109;
+ }
+ if ($passwd eq "") {
+ return 108 if (($passwd = typepasswd()) eq "");
+ }
+ if (verify_password($passwd) == 0) {
+ return 104;
+ }
+ print $so pack("va24a24a1a40", 0x7930, $userid, $passwd, $sex, $email);
+ $so->flush();
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x7931) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 106;
+ }
+ $buf = readso(28);
+ if (unpack("V", $buf) == -1 || unpack("V", $buf) == 4294967295) {
+ if ($defaultlanguage eq "F") {
+ print "Echec à la création du compte [$userid]. Un compte identique existe déjà.\n";
+ } else {
+ print "Account [$userid] creation failed. Same account already exists.\n";
+ }
+ return 107;
+ } else {
+ if ($defaultlanguage eq "F") {
+ printf "Compte [$userid] créé avec succès [id: %d].\n", unpack("V",$buf);
+ } else {
+ printf "Account [$userid] is successfully created [id: %d].\n", unpack("V",$buf);
+ }
+ }
+ return 0;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: deletion of an account
+sub delaccount() {
+ my($userid) = @_;
+ if ($userid eq "") {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un nom de compte svp.\n";
+ print "<exemple> del nomtestasupprimer\n";
+ } else {
+ print "Please input an account name.\n";
+ print "<example> del testnametodelete\n";
+ }
+ return 136;
+ }
+ if (verify_accountname($userid) == 0) {
+ return 102;
+ }
+ if ($defaultlanguage eq "F") {
+ print "** Etes-vous vraiment sûr de vouloir SUPPRIMER le compte [$userid]? (o/n) ";
+ } else {
+ print "** Are you really sure to DELETE account [$userid]? (y/n) ";
+ }
+ if (lc(substr(<STDIN>, 0, 1)) !~ /[oy]/) {
+ if ($defaultlanguage eq "F") {
+ print "Suppression annulée\n.";
+ } else {
+ print "Deletion canceled\n";
+ }
+ return 121;
+ }
+ print $so pack("va24", 0x7932, $userid);
+ $so->flush();
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x7933) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 122;
+ }
+ $buf = readso(28);
+ my($id2, $name) = unpack("Va24", $buf);
+ while (length($name) > 0 && substr($name, length($name)-1, 1) eq chr(0)) {
+ chop($name);
+ };
+ if ($id2 == -1 || $id2 == 4294967295) {
+ if ($defaultlanguage eq "F") {
+ print "Echec de la suppression du compte [$userid]. Le compte n'existe pas.\n";
+ } else {
+ print "Account [$userid] deletion failed. Account doesn't exist.\n";
+ }
+ return 123;
+ } else {
+ if ($defaultlanguage eq "F") {
+ print "Compte [$name][id: $id2] SUPPRIME avec succès.\n";
+ } else {
+ print "Account [$name][id: $id2] is successfully DELETED.\n";
+ }
+ }
+ return 0;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: modification of a password
+sub changepasswd() {
+ my($userid, $passwd) = @_;
+ if ($userid eq "") {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un nom de compte svp.\n";
+ print "<exemple> passwd nomtest nouveaumotdepasse\n";
+ } else {
+ print "Please input an account name.\n";
+ print "<example> passwd testname newpassword\n";
+ }
+ return 136;
+ }
+ if (verify_accountname($userid) == 0) {
+ return 102;
+ }
+ if ($passwd eq "") {
+ return 134 if (($passwd = typepasswd()) eq "");
+ }
+ if (verify_password($passwd) == 0) {
+ return 131;
+ }
+ print $so pack("va24a24", 0x7934, $userid,$passwd);
+ $so->flush();
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x7935) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 132;
+ }
+ $buf = readso(28);
+ my($id2, $name) = unpack("Va24", $buf);
+ while (length($name) > 0 && substr($name, length($name)-1, 1) eq chr(0)) {
+ chop($name);
+ };
+ if ($id2 == -1 || $id2 == 4294967295) {
+ if ($defaultlanguage eq "F") {
+ print "Echec de la modification du mot de passe du compte [$userid].\n";
+ print "Le compte [$userid] n'existe pas.\n";
+ } else {
+ print "Account [$userid] password changing failed.\n";
+ print "Account [$userid] doesn't exist.\n";
+ }
+ return 133;
+ } else {
+ if ($defaultlanguage eq "F") {
+ print "Modification du mot de passe du compte [$name][id: $id2] réussie.\n";
+ } else {
+ print "Account [$name][id: $id2] password successfully changed.\n";
+ }
+ }
+ return 130;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: modification of an account e-mail
+sub changeemail() {
+ my($userid, $email) = @_;
+ if ($userid eq "") {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un nom de compte svp.\n";
+ print "<exemple> email testname nouveauemail\n";
+ } else {
+ print "Please input an account name.\n";
+ print "<example> email testname newemail\n";
+ }
+ return 136;
+ }
+ if (verify_accountname($userid) == 0) {
+ return 102;
+ }
+ if (length($email) < 3) {
+ if ($defaultlanguage eq "F") {
+ print "Email trop courte [$email]. Entrez une e-mail valide svp.\n";
+ } else {
+ print "Email is too short [$email]. Please input a valid e-mail.\n";
+ }
+ return 109;
+ }
+ if (length($email) > 39) {
+ if ($defaultlanguage eq "F") {
+ print "Email trop longue [$email]. Entrez une e-mail de 39 caractères maximum svp.\n";
+ } else {
+ print "Email is too long [$email]. Please input an e-mail with 39 bytes at the most.\n";
+ }
+ return 109;
+ }
+ if (verify_email($email) == 0) {
+ if ($defaultlanguage eq "F") {
+ print "Email incorrect [$email]. Entrez une e-mail valide svp.\n";
+ } else {
+ print "Invalid email [$email]. Please input a valid e-mail.\n";
+ }
+ return 109;
+ }
+ print $so pack("va24a40", 0x7940, $userid, $email);
+ $so->flush();
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x7941) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 162;
+ }
+ $buf = readso(28);
+ my($id2, $name) = unpack("Va24", $buf);
+ while (length($name) > 0 && substr($name, length($name)-1, 1) eq chr(0)) {
+ chop($name);
+ };
+ if ($id2 == -1 || $id2 == 4294967295) {
+ if ($defaultlanguage eq "F") {
+ print "Echec de la modification de l'e-mail du compte [$userid].\n";
+ print "Le compte [$userid] n'existe pas.\n";
+ } else {
+ print "Account [$userid] e-mail changing failed.\n";
+ print "Account [$userid] doesn't exist.\n";
+ }
+ return 133;
+ } else {
+ if ($defaultlanguage eq "F") {
+ print "Modification de l'e-mail du compte [$name][id: $id2] réussie.\n";
+ } else {
+ print "Account [$name][id: $id2] e-mail successfully changed.\n";
+ }
+ }
+ return 160;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: search of accounts
+sub searchaccount() {
+ my($p1, $p2) = @_;
+ my($exp) = ("");
+ if ($p1 eq "-e" || $p1 eq "-r" || $p1 eq "--regex" || $p1 eq "--expr") {
+ if ($p2 eq "") {
+ if ($defaultlanguage eq "F") {
+ print "Entrez une expression régulière ou utilisez 'ls' pour avoir tous les comptes.\n";
+ } else {
+ print "Input a regular expression or use 'ls' to obtain all accounts.\n";
+ }
+ return 141;
+ }
+ $exp = $p2;
+ } else {
+ if ($p1 eq "") {
+ if ($defaultlanguage eq "F") {
+ print "Entrez une chaîne ou utilisez 'ls' pour avoir tous les comptes.\n";
+ } else {
+ print "Input a string or use 'ls' to obtain all accounts.\n";
+ }
+ return 141;
+ }
+ my($c) = 0;
+ $exp = lc($p1);
+ $exp =~ s/([\@])/\\$1/g;
+ $c += $exp =~ s/([\-\[\]])/\\$1/g;
+ $c += $exp =~ s/([\*\?])/.$1/g;
+ $c += $exp =~ s/\\\[(.)\\\-(.)\\\]/[$1-$2]/g;
+ $exp = "^$exp\$" if $c;
+ }
+ if (eval{ "" =~ /$exp/; }, $@) {
+ if ($defaultlanguage eq "F") {
+ print "Expression régulière non reconnue.\n";
+ } else {
+ print "Regular-Expression compiling failed.\n";
+ }
+ return 141;
+ }
+ my($i);
+ my($n, $st) = (0, 0);
+ # 0123456789 01 01234567890123456789012301234 012345 0123456789012345678901234567
+ if ($defaultlanguage eq "F") {
+ print " id_compte GM nom_utilisateur sexe count statut\n";
+ } else {
+ print "account_id GM user_name sex count state\n";
+ }
+ print "-------------------------------------------------------------------------------\n";
+ while(1) {
+ print $so pack("vV2", 0x7920, $st, 0);
+ $so->flush();
+ $buf = readso(4);
+ if (unpack("v", $buf) != 0x7921) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ exit(10);
+ }
+ my($len) = unpack("x2v", $buf);
+ last if ($len <= 4);
+ for($i = 4; $i < $len; $i += 38) {
+ my(@dat) = unpack("VCa24cVV", readso(38));
+ $st = $dat[0] + 1;
+ next if (lc($dat[2]) !~ /$exp/);
+ printf "%10d %2s %-24s%-5s %6d %-27s\n", $dat[0],
+ ($dat[1] == 0 ? " " : $dat[1]),
+ $dat[2],
+ ($defaultlanguage eq "F" ? ("Femme","Male","Servr")[$dat[3]] : ("Femal","Male","Servr")[$dat[3]]),
+ $dat[4],
+ (($defaultlanguage eq "F" ? "Compte Ok" : "Account OK"),
+ "Unregistered ID",
+ "Incorrect Password",
+ "This ID is expired",
+ "Rejected from Server",
+ "Blocked by the GM Team", # You have been blocked by the GM Team
+ "Your EXE file is too old", # Your Game's EXE file is not the latest version
+ "Banishement or\n Prohibited to login until %s", # You are Prohibited to log in until %s
+ "Server is over populated", # Server is jammed due to over populated
+ "No MSG",
+ "This ID is totally erased")[$dat[5] == 100 ? 10 : $dat[5]]; # This ID has been totally erased
+ $n++;
+ }
+ }
+ if ($defaultlanguage eq "F") {
+ if ($n == 0) {
+ print "Aucun compte trouvé.\n";
+ } elsif ($n == 1) {
+ print "1 compte trouvé.\n";
+ } else {
+ print "$n comptes trouvés.\n";
+ }
+ } else {
+ if ($n == 0) {
+ print "No account found.\n";
+ } elsif ($n == 1) {
+ print "1 account found.\n";
+ } else {
+ print "$n accounts found.\n";
+ }
+ }
+ return 0;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: modify the sex of an account
+sub changesex() {
+ my($userid, $sex) = @_;
+ if ($userid eq "" || !defined($userid)) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un nom de compte svp.\n";
+ print "<exemple> sex nomtest Male\n";
+ } else {
+ print "Please input an account name.\n";
+ print "<example> sex testname Male\n";
+ }
+ return 136;
+ }
+ if (verify_accountname($userid) == 0) {
+ return 102;
+ }
+# if ($userid =~ /[^A-Za-z0-9\@-_]/) {
+# if ($defaultlanguage eq "F") {
+# print "Caractère interdit trouvé dans le nom du compte ".$`."[${&}]${'}\n";
+# } else {
+# print "Illegal character found in the account name ".$`."[${&}]${'}\n";
+# }
+# return 101;
+# }
+ $sex = uc(substr($sex, 0, 1));
+ if ($sex !~ /^[MF]$/) {
+ if ($defaultlanguage eq "F") {
+ print "Sexe incorrect [$sex]. Entrez M ou F svp.\n";
+ } else {
+ print "Illegal gender [$sex]. Please input M or F.\n";
+ }
+ return 103;
+ }
+ print $so pack("va24a1", 0x793c, $userid, $sex);
+ $so->flush();
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x793d) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 152;
+ }
+ $buf = readso(28);
+ my($id2, $name) = unpack("Va24", $buf);
+ while (length($name) > 0 && substr($name, length($name)-1, 1) eq chr(0)) {
+ chop($name);
+ };
+ if ($id2 == -1 || $id2 == 4294967295) {
+ if ($defaultlanguage eq "F") {
+ print "Echec du changement du sexe du compte [$userid].\n";
+ print "Le compte n'existe pas ou le sexe est déjà celui demandé.\n";
+ } else {
+ print "Account [$userid] sex changing failed.\n";
+ print "Account doesn't exist or the sex is already the good sex.\n";
+ }
+ } else {
+ if ($defaultlanguage eq "F") {
+ print "Sexe du compte [$name][id: $id2] changé avec succès.\n";
+ } else {
+ print "Account [$name][id: $id2] sex successfully changed.\n";
+ }
+ }
+ return 0;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: modify the GM level of an account
+sub changegmlevel() {
+ my($userid, $gm_level) = @_;
+ if ($userid eq "" || !defined($userid)) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un nom de compte svp.\n";
+ print "<exemple> gm nomtest 80\n";
+ } else {
+ print "Please input an account name.\n";
+ print "<example> gm testname 80\n";
+ }
+ return 136;
+ }
+ if (verify_accountname($userid) == 0) {
+ return 102;
+ }
+# if ($userid =~ /[^A-Za-z0-9\@-_]/) {
+# if ($defaultlanguage eq "F") {
+# print "Caractère interdit trouvé dans le nom du compte ".$`."[${&}]${'}\n";
+# } else {
+# print "Illegal character found in the account name ".$`."[${&}]${'}\n";
+# }
+# return 101;
+# }
+ $gm_level = int($gm_level);
+ if ($gm_level < 0 || $gm_level > 99) {
+ if ($defaultlanguage eq "F") {
+ print "Niveau de GM incorrect [$gm_level]. Entrez une valeur de 0 à 99 svp.\n";
+ } else {
+ print "Illegal GM level [$gm_level]. Please input a value from 0 to 99.\n";
+ }
+ return 103;
+ }
+ print $so pack("va24C", 0x793e, $userid, $gm_level);
+ $so->flush();
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x793f) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 152;
+ }
+ $buf = readso(28);
+ my($id2, $name) = unpack("Va24", $buf);
+ while (length($name) > 0 && substr($name, length($name)-1, 1) eq chr(0)) {
+ chop($name);
+ };
+ if ($id2 == -1 || $id2 == 4294967295) {
+ if ($defaultlanguage eq "F") {
+ print "Echec du changement du niveau de GM du compte [$userid].\n";
+ print "Le compte n'existe pas, le niveau de GM est déjà celui demandé,\n";
+ print "ou il est impossible de modifier le fichier des comptes GM.\n";
+ } else {
+ print "Account [$userid] GM level changing failed.\n";
+ print "Account doesn't exist, the GM level is already the good GM level,\n";
+ print "or it's impossible to modify the GM accounts file.\n";
+ }
+ } else {
+ if ($defaultlanguage eq "F") {
+ print "Niveau de GM du compte [$name][id: $id2] changé avec succès.\n";
+ } else {
+ print "Account [$name][id: $id2] GM level successfully changed.\n";
+ }
+ }
+ return 0;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Modification of a state
+sub changestate {
+ my($userid, $s, $error_message) = @_;
+ # Valid values: 0: ok, or value of the 0x006a packet + 1
+ if ($s eq "" || (($s < 0 || $s > 9) && $s != 100)) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez une des valeurs suivantes svp:\n";
+ print " 0 = Compte ok 6 = Your Game's EXE file is not the latest version\n";
+ } else {
+ print "Please input one of these values:\n";
+ print " 0 = Account ok 6 = Your Game's EXE file is not the latest version\n";
+ }
+ print " 1 = Unregistered ID 7 = You are Prohibited to log in until %s\n";
+ print " 2 = Incorrect Password 8 = Server is jammed due to over populated\n";
+ print " 3 = This ID is expired 9 = No MSG\n";
+ print " 4 = Rejected from Server 100 = This ID has been totally erased\n";
+ print " 5 = You have been blocked by the GM Team\n";
+ if ($defaultlanguage eq "F") {
+ print "<exemples> state nomtest 5\n";
+ print " state nomtest 7 fin de votre ban\n";
+ print " block <nom du compte>\n";
+ print " unblock <nom du compte>\n";
+ } else {
+ print "<examples> state testname 5\n";
+ print " state testname 7 end of your ban\n";
+ print " block <account name>\n";
+ print " unblock <account name>\n";
+ }
+ return 151;
+ }
+ if ($userid eq "") {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un nom de compte svp.\n";
+ print "<exemples> state nomtest 5\n";
+ print " state nomtest 7 fin de votre ban\n";
+ print " block <nom du compte>\n";
+ print " unblock <nom du compte>\n";
+ } else {
+ print "Please input an account name.\n";
+ print "<examples> state testname 5\n";
+ print " state testname 7 end of your ban\n";
+ print " block <account name>\n";
+ print " unblock <account name>\n";
+ }
+ return 136;
+ }
+ if (verify_accountname($userid) == 0) {
+ return 102;
+ }
+ if ($s != 7) {
+ $error_message = "-";
+ } else {
+ if (length($error_message) < 1) {
+ if ($defaultlanguage eq "F") {
+ print "Message d'erreur trop court. Entrez un message de 1-19 caractères.\n";
+ } else {
+ print "Error message is too short. Please input a message of 1-19 bytes.\n";
+ }
+ return 102;
+ }
+ if (length($error_message) > 19) {
+ if ($defaultlanguage eq "F") {
+ print "Message d'erreur trop long. Entrez un message de 1-19 caractères.\n";
+ } else {
+ print "Error message is too long. Please input a message of 1-19 bytes.\n";
+ }
+ return 102;
+ }
+ }
+ print $so pack("va24Va20", 0x7936, $userid, $s, $error_message);
+ $so->flush();
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x7937) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 152;
+ }
+ $buf = readso(32);
+ my(@dat) = unpack("Va24V", $buf);
+ while (length($dat[1]) > 0 && substr($dat[1], length($dat[1])-1, 1) eq chr(0)) {
+ chop($dat[1]);
+ };
+ if ($dat[0] != -1 && $dat[0] != 4294967295) {
+ if ($defaultlanguage eq "F") {
+ print "Statut du compte [$dat[1]][id: $dat[0]] changé avec succès en [";
+ } else {
+ print "Account [$dat[1]][id: $dat[0]] state successfully changed in [";
+ }
+ print ((($defaultlanguage eq "F" ? "Compte Ok" : "Account OK"),
+ "Unregistered ID",
+ "Incorrect Password",
+ "This ID is expired",
+ "Rejected from Server",
+ "You have been blocked by the GM Team",
+ "Your Game's EXE file is not the latest version",
+ "You are Prohibited to log in until %s",
+ "Server is jammed due to over populated",
+ "No MSG",
+ "This ID has been totally erased")[$dat[2] == 100 ? 10 : $dat[2]]);
+ print "].\n";
+ } else {
+ if ($defaultlanguage eq "F") {
+ print "Echec du changement du statut du compte [$userid]. Le compte n'existe pas.\n";
+ } else {
+ print "Account [$userid] state changing failed. Account doesn't exist.\n";
+ }
+ }
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Displaying of the number of online players
+sub getlogincount {
+ # Request to the login-server
+ print $so pack("v", 0x7938);
+ $so->flush();
+
+ $buf = readso(4);
+ # Connection failed
+ if (unpack("v", $buf) != 0x7939) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ exit(3);
+ }
+
+ # Get length of the received packet
+ my($len) = unpack("x2v", $buf) - 4;
+
+ # Read information of the servers
+ if ($len < 1) {
+ if ($defaultlanguage eq "F") {
+ printf " Aucun serveur n'est connecté au login serveur.\n";
+ } else {
+ printf " No server is connected to the login-server.\n";
+ }
+ } else {
+ my(@slist) = ();
+ for(; $len > 0; $len -= 32) {
+ my($name, $count) = unpack("x6 a20 V", readso(32));
+ $name = substr($name, 0, index($name, "\0"));
+ push @slist, [ $name, $count ];
+ }
+ # Displaying of result
+ my($i);
+ if ($defaultlanguage eq "F") {
+ printf " Nombre de joueurs en ligne (serveur: nb):\n";
+ } else {
+ printf " Number of online players (server: number).\n";
+ }
+ foreach $i(@slist) {
+ printf " %-20s : %5d\n", $i->[0], $i->[1];
+ }
+ }
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Modification of a memo field
+sub changememo {
+ my($userid, $memo) = @_;
+ if ($userid eq "") {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un nom de compte svp.\n";
+ print "<exemple> memo nomtest nouveau memo\n";
+ } else {
+ print "Please input an account name.\n";
+ print "<example> memo testname new memo\n";
+ }
+ return 136;
+ }
+ if (verify_accountname($userid) == 0) {
+ return 102;
+ }
+ if (length($memo) > 254) {
+ if ($defaultlanguage eq "F") {
+ print "Mémo trop long (".length($memo)." caractères).\n";
+ print "Entrez un mémo de 254 caractères maximum svp.\n";
+ } else {
+ print "Memo is too long (".length($memo)." characters).\n";
+ print "Please input a memo of 254 bytes at the maximum.\n";
+ }
+ return 102;
+ }
+ if (length($memo) == 0) {
+ print $so pack("va24v", 0x7942, $userid, 0);
+ } else {
+ print $so pack("va24va".length($memo), 0x7942, $userid, length($memo), $memo);
+ }
+ $so->flush();
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x7943) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 152;
+ }
+ $buf = readso(28);
+ my($id2, $name) = unpack("Va24", $buf);
+ while (length($name) > 0 && substr($name, length($name)-1, 1) eq chr(0)) {
+ chop($name);
+ };
+ if ($id2 == -1 || $id2 == 4294967295) {
+ if ($defaultlanguage eq "F") {
+ print "Echec du changement du mémo du compte [$userid]. Le compte n'existe pas.\n";
+ } else {
+ print "Account [$userid] memo changing failed. Account doesn't exist.\n";
+ }
+ } else {
+ if ($defaultlanguage eq "F") {
+ print "Mémo du compte [$name][id: $id2] changé avec succès.\n";
+ } else {
+ print "Account [$name][id: $id2] memo successfully changed.\n";
+ }
+ }
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Request to obtain an account id
+sub idaccount() {
+ my($userid) = @_;
+ if ($userid eq "") {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un nom de compte svp.\n";
+ print "<exemple> id nomtest\n";
+ } else {
+ print "Please input an account name.\n";
+ print "<example> id testname\n";
+ }
+ return 136;
+ }
+ if (verify_accountname($userid) == 0) {
+ return 102;
+ }
+ print $so pack("va24", 0x7944, $userid);
+ $so->flush();
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x7945) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 122;
+ }
+ $buf = readso(28);
+ my($id2, $name) = unpack("Va24", $buf);
+ while (length($name) > 0 && substr($name, length($name)-1, 1) eq chr(0)) {
+ chop($name);
+ };
+ if ($id2 == -1 || $id2 == 4294967295) {
+ if ($defaultlanguage eq "F") {
+ print "Impossible de trouver l'id du compte [$userid]. Le compte n'existe pas.\n";
+ } else {
+ print "Unabled to find the account [$userid] id. Account doesn't exist.\n";
+ }
+ return 123;
+ } else {
+ if ($defaultlanguage eq "F") {
+ print "Le compte [$name] a pour id: $id2.\n";
+ } else {
+ print "The account [$name] have the id: $id2.\n";
+ }
+ }
+ return 0;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Request to obtain an account name
+sub nameaccount() {
+ my($id) = @_;
+ if ($id < 0) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un id ayant une valeur positive svp.\n";
+ } else {
+ print "Please input a positive value for the id.\n";
+ }
+ return 136;
+ }
+ print $so pack("vV", 0x7946, $id);
+ $so->flush();
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x7947) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 122;
+ }
+ $buf = readso(28);
+ my($id2, $name) = unpack("Va24", $buf);
+ while (length($name) > 0 && substr($name, length($name)-1, 1) eq chr(0)) {
+ chop($name);
+ };
+ if (length($name) == 0 || $name eq "") {
+ if ($defaultlanguage eq "F") {
+ print "Impossible de trouver le nom du compte [id: $id2]. Le compte n'existe pas.\n";
+ } else {
+ print "Unabled to find the account [id: $id2] name. Account doesn't exist.\n";
+ }
+ return 123;
+ } else {
+ if ($defaultlanguage eq "F") {
+ print "Le compte [id: $id2] a pour nom: $name.\n";
+ } else {
+ print "The account [id: $id2] have the name: $name.\n";
+ }
+ }
+ return 0;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Set a validity limit of an account
+sub timesetaccount() {
+ my($userid, $date, $time) = @_;
+ if ($userid eq "") {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un nom de compte svp.\n";
+ print "<exemple>: timeset <nom_du_compte> aaaa/mm/jj [hh:mm:ss]\n";
+ print " timeset <nom_du_compte> 0 (0 = illimité)\n";
+ printf " Heure par défaut [hh:mm:ss]: 23:59:59\n";
+ } else {
+ print "Please input an account name.\n";
+ print "<example>: timeset <account_name> yyyy/mm/dd [hh:mm:ss]\n";
+ print " timeset <account_name> 0 (0 = unlimited)\n";
+ printf " Default time [hh:mm:ss]: 23:59:59\n";
+ }
+ return 136;
+ }
+ if (verify_accountname($userid) == 0) {
+ return 102;
+ }
+ my($year, $month, $day) = split(/[.\-\/]/, $date);
+ my($hour, $minute, $second) = split(/:/, $time);
+ if ($time eq "") {
+ $hour = 23;
+ $minute = 59;
+ $second = 59;
+ }
+ my($timestamp);
+ if ($year eq "" ||
+ ($year != 0 && ($month eq "" || $day eq "" || $hour eq "" || $minute eq "" || $second eq ""))) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez 0 ou une date et une heure svp (format: 0 ou aaaa/mm/jj hh:mm:ss).\n";
+ } else {
+ print "Please input 0 or a date and a time (format: 0 or yyyy/mm/dd hh:mm:ss).\n";
+ }
+ return 102;
+ }
+ if ($year == 0) {
+ $timestamp = 0;
+ } else {
+ if ($year < 70) {
+ $year = $year + 100;
+ }
+ if ($year >= 1900) {
+ $year = $year - 1900;
+ }
+ if ($month < 1 || $month > 12) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un mois correct svp (entre 1 et 12).\n";
+ } else {
+ print "Please give a correct value for the month (from 1 to 12).\n";
+ }
+ return 102;
+ }
+ $month = $month - 1;
+ if ($day < 1 || $day > 31) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un jour correct svp (entre 1 et 31).\n";
+ } else {
+ print "Please give a correct value for the day (from 1 to 31).\n";
+ }
+ return 102;
+ }
+ if ((($month == 3 || $month == 5 || $month == 8 || $month == 10) && $day > 30) ||
+ ($month == 1 && $day > 29)) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un jour correct en fonction du mois svp.\n";
+ } else {
+ print "Please give a correct value for a day of this month.\n";
+ }
+ return 102;
+ }
+ if ($hour < 0 || $hour > 23) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez une heure correcte svp (entre 0 et 23).\n";
+ } else {
+ print "Please give a correct value for the hour (from 0 to 23).\n";
+ }
+ return 102;
+ }
+ if ($minute < 0 || $minute > 59) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez des minutes correctes svp (entre 0 et 59).\n";
+ } else {
+ print "Please give a correct value for the minutes (from 0 to 59).\n";
+ }
+ return 102;
+ }
+ if ($second < 0 || $second > 59) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez des secondes correctes svp (entre 0 et 59).\n";
+ } else {
+ print "Please give a correct value for the seconds (from 0 to 59).\n";
+ }
+ return 102;
+ }
+ $timestamp = POSIX::mktime($second, $minute, $hour, $day, $month, $year, 0, 0, -1); # -1: no winter/summer time modification
+ if ($timestamp == undef) {
+ if ($defaultlanguage eq "F") {
+ print "Date incorrecte.\n";
+ print "Ajoutez 0 ou une date et une heure svp (format: 0 ou aaaa/mm/jj hh:mm:ss).\n";
+ } else {
+ print "Invalid date.\n";
+ print "Please add 0 or a date and a time (format: 0 or yyyy/mm/dd hh:mm:ss).\n";
+ }
+ return 102;
+ }
+ }
+
+ print $so pack("va24V", 0x7948, $userid, $timestamp);
+ $so->flush();
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x7949) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 152;
+ }
+ $buf = readso(32);
+ my(@dat) = unpack("Va24V", $buf);
+ while (length($dat[1]) > 0 && substr($dat[1], length($dat[1])-1, 1) eq chr(0)) {
+ chop($dat[1]);
+ };
+ if ($dat[0] != -1 && $dat[0] != 4294967295) {
+ if ($defaultlanguage eq "F") {
+ print "Limite de validité du compte [$dat[1]][id: $dat[0]] changée avec succès ".
+ ($dat[2] == 0 ? "en [illimité].\n" : "pour être jusqu'au ".(POSIX::ctime($dat[2])));
+ } else {
+ print "Validity Limit of the account [$dat[1]][id: $dat[0]] successfully changed ".
+ ($dat[2] == 0 ? "to [unlimited].\n" : "to be until ".(POSIX::ctime($dat[2])));
+ }
+ # localtime($dat[2]) is also possible to display instead of POSIX::ctime.
+ } else {
+ if ($defaultlanguage eq "F") {
+ print "Echec du changement de la validité du compte [$userid]. Le compte n'existe pas.\n";
+ } else {
+ print "Account [$userid] validity limit changing failed. Account doesn't exist.\n";
+ }
+ }
+
+ return 0;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Add/substract time to the validity limit of an account
+sub timeaddaccount() {
+ my($userid, $modif) = @_;
+ if ($userid eq "") {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un nom de compte svp.\n";
+ print " <exemple> timeadd nomtest +1m-2mn1s-6y\n";
+ print " Cette exemple ajoute 1 mois et 1 seconde, et soustrait 2 minutes\n";
+ print " et 6 ans dans le même temps.\n";
+ } else {
+ print "Please input an account name.\n";
+ print " <example> timeadd testname +1m-2mn1s-6y\n";
+ print " this example adds 1 month and 1 second, and substracts 2 minutes\n";
+ print " and 6 years at the same time.\n";
+ }
+ return 136;
+ }
+ if (verify_accountname($userid) == 0) {
+ return 102;
+ }
+ my($year, $month, $day) = (0, 0 ,0);
+ my($hour, $minute, $second) = (0, 0 ,0);
+
+ $modif = lc($modif);
+ while (length($modif) > 0) {
+ my($value) = int($modif);
+ if ($value == 0) {
+ $modif = substr($modif, 1);
+ } else {
+ if (substr($modif, 0, 1) =~ /[\-\+]/) {
+ $modif = substr($modif, 1);
+ }
+ while (length($modif) > 0 && substr($modif, 0, 1) =~ /[0-9]/) {
+ $modif = substr($modif, 1);
+ }
+ if (index($modif, "s") == 0) {
+ $second = $value;
+ $modif = substr($modif, 1);
+ } elsif (index($modif, "mn") == 0) {
+ $minute = $value;
+ $modif = substr($modif, 2);
+ } elsif (index($modif, "h") == 0) {
+ $hour = $value;
+ $modif = substr($modif, 1);
+ } elsif (index($modif, "d") == 0 || index($modif, "j") == 0) {
+ $day = $value;
+ $modif = substr($modif, 1);
+ } elsif (index($modif, "m") == 0) {
+ $month = $value;
+ $modif = substr($modif, 1);
+ } elsif (index($modif, "y") == 0 || index($modif, "a") == 0) {
+ $year = $value;
+ $modif = substr($modif, 1);
+ } else {
+ $modif = substr($modif, 1);
+ }
+ }
+ }
+
+ if ($defaultlanguage eq "F") {
+ print " année: $year\n";
+ print " mois: $month\n";
+ print " jour: $day\n";
+ print " heure: $hour\n";
+ print " minute: $minute\n";
+ print " seconde: $second\n";
+ } else {
+ print " year: $year\n";
+ print " month: $month\n";
+ print " day: $day\n";
+ print " hour: $hour\n";
+ print " minute: $minute\n";
+ print " second: $second\n";
+ }
+
+ if ($year == 0 && $month == 0 && $day == 0 && $hour == 0 && $minute == 0 && $second == 0) {
+ if ($defaultlanguage eq "F") {
+ print "Vous devez entrer un ajustement avec cette commande, svp:\n";
+ print " Valeur d'ajustement (-1, 1, +1, etc...)\n";
+ print " Element modifié:\n";
+ print " a ou y: année\n";
+ print " m: mois\n";
+ print " j ou d: jour\n";
+ print " h: heure\n";
+ print " mn: minute\n";
+ print " s: seconde\n";
+ print " <exemple> timeadd nomtest +1m-2mn1s-6y\n";
+ print " Cette exemple ajoute 1 mois et 1 seconde, et soustrait 2 minutes\n";
+ print " et 6 ans dans le même temps.\n";
+ } else {
+ print "Please give an adjustment with this command:\n";
+ print " Adjustment value (-1, 1, +1, etc...)\n";
+ print " Modified element:\n";
+ print " a or y: year\n";
+ print " m: month\n";
+ print " j or d: day\n";
+ print " h: hour\n";
+ print " mn: minute\n";
+ print " s: second\n";
+ print " <example> timeadd testname +1m-2mn1s-6y\n";
+ print " this example adds 1 month and 1 second, and substracts 2 minutes\n";
+ print " and 6 years at the same time.\n";
+ }
+ return 137;
+ }
+ if ($year > 127 || $year < -127) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un ajustement d'années correct (de -127 à 127), svp.\n";
+ } else {
+ print "Please give a correct adjustment for the years (from -127 to 127).\n";
+ }
+ return 137;
+ }
+ if ($month > 255 || $month < -255) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un ajustement de mois correct (de -255 à 255), svp.\n";
+ } else {
+ print "Please give a correct adjustment for the months (from -255 to 255).\n";
+ }
+ return 137;
+ }
+ if ($day > 32767 || $day < -32767) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un ajustement de jours correct (de -32767 à 32767), svp.\n";
+ } else {
+ print "Please give a correct adjustment for the days (from -32767 to 32767).\n";
+ }
+ return 137;
+ }
+ if ($hour > 32767 || $hour < -32767) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un ajustement d'heures correct (de -32767 à 32767), svp.\n";
+ } else {
+ print "Please give a correct adjustment for the hours (from -32767 to 32767).\n";
+ }
+ return 137;
+ }
+ if ($minute > 32767 || $minute < -32767) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un ajustement de minutes correct (de -32767 à 32767), svp.\n";
+ } else {
+ print "Please give a correct adjustment for the minutes (from -32767 to 32767).\n";
+ }
+ return 137;
+ }
+ if ($second > 32767 || $second < -32767) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un ajustement de secondes correct (de -32767 à 32767), svp.\n";
+ } else {
+ print "Please give a correct adjustment for the seconds (from -32767 to 32767).\n";
+ }
+ return 137;
+ }
+
+ print $so pack("va24vvvvvv", 0x7950, $userid, $year, $month, $day, $hour, $minute, $second);
+ $so->flush();
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x7951) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 152;
+ }
+ $buf = readso(32);
+ my(@dat) = unpack("Va24V", $buf);
+ while (length($dat[1]) > 0 && substr($dat[1], length($dat[1])-1, 1) eq chr(0)) {
+ chop($dat[1]);
+ };
+ if ($dat[0] == -1 || $dat[0] == 4294967295) {
+ if ($defaultlanguage eq "F") {
+ print "Echec du changement de la validité du compte [$userid]. Le compte n'existe pas.\n";
+ } else {
+ print "Account [$userid] validity limit changing failed. Account doesn't exist.\n";
+ }
+ } elsif ($dat[2] == 0) {
+ if ($defaultlanguage eq "F") {
+ print "Limite de validité du compte [$dat[1]][id: $dat[0]] inchangée.\n";
+ print "Le compte a une validité illimitée ou\n";
+ print "la modification est impossible avec les ajustements demandés.\n";
+ } else {
+ print "Validity limit of the account [$dat[1]][id: $dat[0]] unchanged.\n";
+ print "The account have an unlimited validity limit or\n";
+ print "the changing is impossible with the proposed adjustments.\n";
+ }
+ } else {
+ if ($defaultlanguage eq "F") {
+ print "Limite de validité du compte [$dat[1]][id: $dat[0]] changée avec succès ".
+ ($dat[2] == 0 ? "en [illimité].\n" : "pour être jusqu'au ".(POSIX::ctime($dat[2])));
+ } else {
+ print "Validity limit of the account [$dat[1]][id: $dat[0]] successfully changed ".
+ ($dat[2] == 0 ? "to [unlimited].\n" : "to be until ".(POSIX::ctime($dat[2])));
+ }
+ # localtime($dat[2]) is also possible to display instead of POSIX::ctime.
+ }
+
+ return 0;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Set the final date of a banishment of an account
+sub bansetaccount() {
+ my($userid, $date, $time) = @_;
+ if ($userid eq "") {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un nom de compte svp.\n";
+ print "<exemple>: banset <nom_du_compte> aaaa/mm/jj [hh:mm:ss]\n";
+ print " banset <nom_du_compte> 0 (0 = dé-bani)\n";
+ print " ban/banish aaaa/mm/jj hh:mm:ss <nom du compte>\n";
+ print " unban/unbanish <nom du compte>\n";
+ printf " Heure par défaut [hh:mm:ss]: 23:59:59\n";
+ } else {
+ print "Please input an account name.\n";
+ print "<example>: banset <account_name> yyyy/mm/dd [hh:mm:ss]\n";
+ print " banset <account_name> 0 (0 = un-banished)\n";
+ print " ban/banish yyyy/mm/dd hh:mm:ss <account name>\n";
+ print " unban/unbanish <account name>\n";
+ printf " Default time [hh:mm:ss]: 23:59:59\n";
+ }
+ return 136;
+ }
+ if (verify_accountname($userid) == 0) {
+ return 102;
+ }
+ my($year, $month, $day) = split(/[.\-\/]/, $date);
+ my($hour, $minute, $second) = split(/:/, $time);
+ if ($time eq "") {
+ $hour = 23;
+ $minute = 59;
+ $second = 59;
+ }
+ my($timestamp);
+ if ($year eq "" ||
+ ($year != 0 && ($month eq "" || $day eq "" || $hour eq "" || $minute eq "" || $second eq ""))) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez 0 ou une date et une heure svp (format: 0 ou aaaa/mm/jj hh:mm:ss).\n";
+ } else {
+ print "Please input 0 or a date and a time (format: 0 or yyyy/mm/dd hh:mm:ss).\n";
+ }
+ return 102;
+ }
+ if ($year == 0) {
+ $timestamp = 0;
+ } else {
+ if ($year < 70) {
+ $year = $year + 100;
+ }
+ if ($year >= 1900) {
+ $year = $year - 1900;
+ }
+ if ($month < 1 || $month > 12) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un mois correct svp (entre 1 et 12).\n";
+ } else {
+ print "Please give a correct value for the month (from 1 to 12).\n";
+ }
+ return 102;
+ }
+ $month = $month - 1;
+ if ($day < 1 || $day > 31) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un jour correct svp (entre 1 et 31).\n";
+ } else {
+ print "Please give a correct value for the day (from 1 to 31).\n";
+ }
+ return 102;
+ }
+ if ((($month == 3 || $month == 5 || $month == 8 || $month == 10) && $day > 30) ||
+ ($month == 1 && $day > 29)) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un jour correct en fonction du mois svp.\n";
+ } else {
+ print "Please give a correct value for a day of this month.\n";
+ }
+ return 102;
+ }
+ if ($hour < 0 || $hour > 23) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez une heure correcte svp (entre 0 et 23).\n";
+ } else {
+ print "Please give a correct value for the hour (from 0 to 23).\n";
+ }
+ return 102;
+ }
+ if ($minute < 0 || $minute > 59) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez des minutes correctes svp (entre 0 et 59).\n";
+ } else {
+ print "Please give a correct value for the minutes (from 0 to 59).\n";
+ }
+ return 102;
+ }
+ if ($second < 0 || $second > 59) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez des secondes correctes svp (entre 0 et 59).\n";
+ } else {
+ print "Please give a correct value for the seconds (from 0 to 59).\n";
+ }
+ return 102;
+ }
+ $timestamp = POSIX::mktime($second, $minute, $hour, $day, $month, $year, 0, 0, -1); # -1: no winter/summer time modification
+ if ($timestamp == undef) {
+ if ($defaultlanguage eq "F") {
+ print "Date incorrecte.\n";
+ print "Ajoutez 0 ou une date et une heure svp (format: 0 ou aaaa/mm/jj hh:mm:ss).\n";
+ } else {
+ print "Invalid date.\n";
+ print "Please add 0 or a date and a time (format: 0 or yyyy/mm/dd hh:mm:ss).\n";
+ }
+ return 102;
+ }
+ }
+
+ print $so pack("va24V", 0x794a, $userid, $timestamp);
+ $so->flush();
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x794b) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 152;
+ }
+ $buf = readso(32);
+ my(@dat) = unpack("Va24V", $buf);
+ while (length($dat[1]) > 0 && substr($dat[1], length($dat[1])-1, 1) eq chr(0)) {
+ chop($dat[1]);
+ };
+ if ($dat[0] != -1 && $dat[0] != 4294967295) {
+ if ($defaultlanguage eq "F") {
+ print "Date finale de banissement du compte [$dat[1]][id: $dat[0]] changée avec succès ".
+ ($dat[2] == 0 ? "en [dé-bannie].\n" : "pour être jusqu'au ".(POSIX::ctime($dat[2])));
+ } else {
+ print "Final date of banishment of the account [$dat[1]][id: $dat[0]] successfully changed ".
+ ($dat[2] == 0 ? "to [unbanished].\n" : "to be until ".(POSIX::ctime($dat[2])));
+ }
+ # localtime($dat[2]) is also possible to display instead of POSIX::ctime.
+ } else {
+ if ($defaultlanguage eq "F") {
+ print "Echec du changement de la date finale de banissement du compte [$userid]. Le compte n'existe pas.\n";
+ } else {
+ print "Account [$userid] final date of banishment changing failed. Account doesn't exist.\n";
+ }
+ }
+
+ return 0;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Add/substract time to the final date of a banishment of an account
+sub banaddaccount() {
+ my($userid, $modif) = @_;
+ if ($userid eq "") {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un nom de compte svp.\n";
+ print " <exemple> banadd nomtest +1m-2mn1s-6y\n";
+ print " Cette exemple ajoute 1 mois et 1 seconde, et soustrait 2 minutes\n";
+ print " et 6 ans dans le même temps.\n";
+ } else {
+ print "Please input an account name.\n";
+ print " <example> banadd testname +1m-2mn1s-6y\n";
+ print " this example adds 1 month and 1 second, and substracts 2 minutes\n";
+ print " and 6 years at the same time.\n";
+ }
+ return 136;
+ }
+ if (verify_accountname($userid) == 0) {
+ return 102;
+ }
+ my($year, $month, $day) = (0, 0 ,0);
+ my($hour, $minute, $second) = (0, 0 ,0);
+
+ $modif = lc($modif);
+ while (length($modif) > 0) {
+ my($value) = int($modif);
+ if ($value == 0) {
+ $modif = substr($modif, 1);
+ } else {
+ if (substr($modif, 0, 1) =~ /[\-\+]/) {
+ $modif = substr($modif, 1);
+ }
+ while (length($modif) > 0 && substr($modif, 0, 1) =~ /[0-9]/) {
+ $modif = substr($modif, 1);
+ }
+ if (index($modif, "s") == 0) {
+ $second = $value;
+ $modif = substr($modif, 1);
+ } elsif (index($modif, "mn") == 0) {
+ $minute = $value;
+ $modif = substr($modif, 2);
+ } elsif (index($modif, "h") == 0) {
+ $hour = $value;
+ $modif = substr($modif, 1);
+ } elsif (index($modif, "d") == 0 || index($modif, "j") == 0) {
+ $day = $value;
+ $modif = substr($modif, 1);
+ } elsif (index($modif, "m") == 0) {
+ $month = $value;
+ $modif = substr($modif, 1);
+ } elsif (index($modif, "y") == 0 || index($modif, "a") == 0) {
+ $year = $value;
+ $modif = substr($modif, 1);
+ } else {
+ $modif = substr($modif, 1);
+ }
+ }
+ }
+
+ if ($defaultlanguage eq "F") {
+ print " année: $year\n";
+ print " mois: $month\n";
+ print " jour: $day\n";
+ print " heure: $hour\n";
+ print " minute: $minute\n";
+ print " seconde: $second\n";
+ } else {
+ print " year: $year\n";
+ print " month: $month\n";
+ print " day: $day\n";
+ print " hour: $hour\n";
+ print " minute: $minute\n";
+ print " second: $second\n";
+ }
+
+ if ($year == 0 && $month == 0 && $day == 0 && $hour == 0 && $minute == 0 && $second == 0) {
+ if ($defaultlanguage eq "F") {
+ print "Vous devez entrer un ajustement avec cette commande, svp:\n";
+ print " Valeur d'ajustement (-1, 1, +1, etc...)\n";
+ print " Element modifié:\n";
+ print " a ou y: année\n";
+ print " m: mois\n";
+ print " j ou d: jour\n";
+ print " h: heure\n";
+ print " mn: minute\n";
+ print " s: seconde\n";
+ print " <exemple> banadd nomtest +1m-2mn1s-6y\n";
+ print " Cette exemple ajoute 1 mois et 1 seconde, et soustrait 2 minutes\n";
+ print " et 6 ans dans le même temps.\n";
+ } else {
+ print "Please give an adjustment with this command:\n";
+ print " Adjustment value (-1, 1, +1, etc...)\n";
+ print " Modified element:\n";
+ print " a or y: year\n";
+ print " m: month\n";
+ print " j or d: day\n";
+ print " h: hour\n";
+ print " mn: minute\n";
+ print " s: second\n";
+ print " <example> banadd testname +1m-2mn1s-6y\n";
+ print " this example adds 1 month and 1 second, and substracts 2 minutes\n";
+ print " and 6 years at the same time.\n";
+ }
+ return 137;
+ }
+ if ($year > 127 || $year < -127) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un ajustement d'années correct (de -127 à 127), svp.\n";
+ } else {
+ print "Please give a correct adjustment for the years (from -127 to 127).\n";
+ }
+ return 137;
+ }
+ if ($month > 255 || $month < -255) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un ajustement de mois correct (de -255 à 255), svp.\n";
+ } else {
+ print "Please give a correct adjustment for the months (from -255 to 255).\n";
+ }
+ return 137;
+ }
+ if ($day > 32767 || $day < -32767) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un ajustement de jours correct (de -32767 à 32767), svp.\n";
+ } else {
+ print "Please give a correct adjustment for the days (from -32767 to 32767).\n";
+ }
+ return 137;
+ }
+ if ($hour > 32767 || $hour < -32767) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un ajustement d'heures correct (de -32767 à 32767), svp.\n";
+ } else {
+ print "Please give a correct adjustment for the hours (from -32767 to 32767).\n";
+ }
+ return 137;
+ }
+ if ($minute > 32767 || $minute < -32767) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un ajustement de minutes correct (de -32767 à 32767), svp.\n";
+ } else {
+ print "Please give a correct adjustment for the minutes (from -32767 to 32767).\n";
+ }
+ return 137;
+ }
+ if ($second > 32767 || $second < -32767) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un ajustement de secondes correct (de -32767 à 32767), svp.\n";
+ } else {
+ print "Please give a correct adjustment for the seconds (from -32767 to 32767).\n";
+ }
+ return 137;
+ }
+
+ print $so pack("va24vvvvvv", 0x794c, $userid, $year, $month, $day, $hour, $minute, $second);
+ $so->flush();
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x794d) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 152;
+ }
+ $buf = readso(32);
+ my(@dat) = unpack("Va24V", $buf);
+ while (length($dat[1]) > 0 && substr($dat[1], length($dat[1])-1, 1) eq chr(0)) {
+ chop($dat[1]);
+ };
+ if ($dat[0] == -1 || $dat[0] == 4294967295) {
+ if ($defaultlanguage eq "F") {
+ print "Echec du changement de la date finale de banissement du compte [$userid]. Le compte n'existe pas.\n";
+ } else {
+ print "Account [$userid] final date of banishment changing failed. Account doesn't exist.\n";
+ }
+ } else {
+ if ($defaultlanguage eq "F") {
+ print "Date finale de banissement du compte [$dat[1]][id: $dat[0]] changée avec succès ".
+ ($dat[2] == 0 ? "en [dé-bannie].\n" : "pour être jusqu'au ".(POSIX::ctime($dat[2])));
+ } else {
+ print "Final date of banishment of the account [$dat[1]][id: $dat[0]] successfully changed ".
+ ($dat[2] == 0 ? "to [unbanished].\n" : "to be until ".(POSIX::ctime($dat[2])));
+ }
+ # localtime($dat[2]) is also possible to display instead of POSIX::ctime.
+ }
+
+ return 0;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Request to displaying information about an account (by its name)
+sub whoaccount() {
+ my($userid) = @_;
+ if ($userid eq "") {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un nom de compte svp.\n";
+ print "<exemple> who nomtest\n";
+ } else {
+ print "Please input an account name.\n";
+ print "<example> who testname\n";
+ }
+ return 136;
+ }
+ if (verify_accountname($userid) == 0) {
+ return 102;
+ }
+
+ print $so pack("va24", 0x7952, $userid);
+ $so->flush();
+
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x7953) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 122;
+ }
+ my($id2, $GM_level, $name, $sex, $count, $status, $error_message, $last_login, $last_ip, $email, $validite, $ban_date, $memo_size) = unpack("VCa24cVVa20a24a16a40VVv", readso(148));
+ my($memo) = "";
+ if ($memo_size > 0) {
+ $memo = unpack("a".$memo_size, readso($memo_size));
+ }
+ while (length($name) > 0 && substr($name, length($name)-1, 1) eq chr(0)) {
+ chop($name);
+ };
+ while (length($error_message) > 0 && substr($error_message, length($error_message)-1, 1) eq chr(0)) {
+ chop($error_message);
+ };
+ while (length($last_login) > 0 && substr($last_login, length($last_login)-1, 1) eq chr(0)) {
+ chop($last_login);
+ };
+ while (length($last_ip) > 0 && substr($last_ip, length($last_ip)-1, 1) eq chr(0)) {
+ chop($last_ip);
+ };
+ while (length($email) > 0 && substr($email, length($email)-1, 1) eq chr(0)) {
+ chop($email);
+ };
+ while (length($memo) > 0 && substr($memo, length($memo)-1, 1) eq chr(0)) {
+ chop($memo);
+ };
+
+ if ($id2 == -1 || $id2 == 4294967295) {
+ if ($defaultlanguage eq "F") {
+ print "Impossible de trouver le compte [$userid]. Le compte n'existe pas.\n";
+ } else {
+ print "Unabled to find the account [$userid]. Account doesn't exist.\n";
+ }
+ return 123;
+ } else {
+ if ($defaultlanguage eq "F") {
+ print "Le compte [$userid] a les caractéristiques suivantes:\n";
+ } else {
+ print "The account [$userid] is set with:\n";
+ }
+ if ($GM_level == 0) {
+ print " Id: $id2 (non-GM)\n";
+ } else {
+ if ($defaultlanguage eq "F") {
+ print " Id: $id2 (GM niveau $GM_level)\n";
+ } else {
+ print " Id: $id2 (GM level $GM_level)\n";
+ }
+ }
+ if ($defaultlanguage eq "F") {
+ print " Nom: '$name'\n";
+ print " Sexe: ".("Femme", "Male", "Serveur")[$sex]."\n";
+ } else {
+ print " Name: '$name'\n";
+ print " Sex: ".("Female", "Male", "Server")[$sex]."\n";
+ }
+ print " E-mail: $email\n";
+ if ($status == 7) {
+ print " Statut: 7 [You are Prohibited to log in until $error_message]\n";
+ } else {
+ print " Statut: $status [".(
+ ($defaultlanguage eq "F" ? "Compte Ok" : "Account OK"),
+ "Unregistered ID",
+ "Incorrect Password",
+ "This ID is expired",
+ "Rejected from Server",
+ "You have been blocked by the GM Team",
+ "Your Game's EXE file is not the latest version",
+ "You are Prohibited to log in until %s",
+ "Server is jammed due to over populated",
+ "No MSG",
+ "This ID is totally erased")[$status == 100 ? 10 : $status]."]\n";
+ }
+ if ($defaultlanguage eq "F") {
+ print " Banissement: ".($ban_date == 0 ? "non banni.\n" : "jusqu'au ".(POSIX::ctime($ban_date)));
+ print " Compteur: $count connexion".("s", "")[$count > 1 ? 0 : 1]."\n";
+ print " Dernière connexion le: $last_login (ip: $last_ip)\n";
+ print " Limite de validité: ".($validite == 0 ? "illimité.\n" : "jusqu'au ".(POSIX::ctime($validite)));
+ } else {
+ print " Banishment: ".($ban_date == 0 ? "not banished.\n" : "until ".(POSIX::ctime($ban_date)));
+ print " Count: $count connection".("s", "")[$count > 1 ? 0 : 1]."\n";
+ print " Last connection at: $last_login (ip: $last_ip)\n";
+ print " Validity limit: ".($validite == 0 ? "unlimited.\n" : "until ".(POSIX::ctime($validite)));
+ }
+ print " Memo: '$memo'\n";
+ }
+ return 0;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Request to displaying information about an account (by its id)
+sub infoaccount() {
+ my($id) = @_;
+ if ($id < 0) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un id ayant une valeur positive svp.\n";
+ } else {
+ print "Please input a positive value for the id.\n";
+ }
+ return 136;
+ }
+
+ print $so pack("vV", 0x7954, $id);
+ $so->flush();
+
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x7953) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 122;
+ }
+ my($id2, $GM_level, $name, $sex, $count, $status, $error_message, $last_login, $last_ip, $email, $validite, $ban_date, $memo_size) = unpack("VCa24cVVa20a24a16a40VVv", readso(148));
+ my($memo) = "";
+ if ($memo_size > 0) {
+ $memo = unpack("a".$memo_size, readso($memo_size));
+ }
+ while (length($name) > 0 && substr($name, length($name)-1, 1) eq chr(0)) {
+ chop($name);
+ };
+ while (length($error_message) > 0 && substr($error_message, length($error_message)-1, 1) eq chr(0)) {
+ chop($error_message);
+ };
+ while (length($last_login) > 0 && substr($last_login, length($last_login)-1, 1) eq chr(0)) {
+ chop($last_login);
+ };
+ while (length($last_ip) > 0 && substr($last_ip, length($last_ip)-1, 1) eq chr(0)) {
+ chop($last_ip);
+ };
+ while (length($email) > 0 && substr($email, length($email)-1, 1) eq chr(0)) {
+ chop($email);
+ };
+ while (length($memo) > 0 && substr($memo, length($memo)-1, 1) eq chr(0)) {
+ chop($memo);
+ };
+
+ if (length($name) == 0 || $name eq "") {
+ if ($defaultlanguage eq "F") {
+ print "Impossible de trouver le nom du compte [id: $id2]. Le compte n'existe pas.\n";
+ } else {
+ print "Unabled to find the account [id: $id2] name. Account doesn't exist.\n";
+ }
+ return 123;
+ } else {
+ if ($defaultlanguage eq "F") {
+ print "Le compte [id: $id2] a les caractéristiques suivantes:\n";
+ } else {
+ print "The account [id: $id2] is set with:\n";
+ }
+ if ($GM_level == 0) {
+ print " Id: $id2 (non-GM)\n";
+ } else {
+ if ($defaultlanguage eq "F") {
+ print " Id: $id2 (GM niveau $GM_level)\n";
+ } else {
+ print " Id: $id2 (GM level $GM_level)\n";
+ }
+ }
+ if ($defaultlanguage eq "F") {
+ print " Nom: '$name'\n";
+ print " Sexe: ".("Femme", "Male", "Serveur")[$sex]."\n";
+ } else {
+ print " Name: '$name'\n";
+ print " Sex: ".("Female", "Male", "Server")[$sex]."\n";
+ }
+ print " E-mail: $email\n";
+ if ($status == 7) {
+ print " Statut: 7 [You are Prohibited to log in until $error_message]\n";
+ } else {
+ print " Statut: $status [".(
+ ($defaultlanguage eq "F" ? "Compte Ok" : "Account OK"),
+ "Unregistered ID",
+ "Incorrect Password",
+ "This ID is expired",
+ "Rejected from Server",
+ "You have been blocked by the GM Team",
+ "Your Game's EXE file is not the latest version",
+ "You are Prohibited to log in until %s",
+ "Server is jammed due to over populated",
+ "No MSG",
+ "This ID is totally erased")[$status == 100 ? 10 : $status]."]\n";
+ }
+ if ($defaultlanguage eq "F") {
+ print " Banissement: ".($ban_date == 0 ? "non banni.\n" : "jusqu'au ".(POSIX::ctime($ban_date)));
+ print " Compteur: $count connexion".("s", "")[$count > 1 ? 0 : 1]."\n";
+ print " Dernière connexion le: $last_login (ip: $last_ip)\n";
+ print " Limite de validité: ".($validite == 0 ? "illimité.\n" : "jusqu'au ".(POSIX::ctime($validite)));
+ } else {
+ print " Banishment: ".($ban_date == 0 ? "not banished.\n" : "until ".(POSIX::ctime($ban_date)));
+ print " Count: $count connection".("s", "")[$count > 1 ? 0 : 1]."\n";
+ print " Last connection at: $last_login (ip: $last_ip)\n";
+ print " Validity limit: ".($validite == 0 ? "unlimited.\n" : "until ".(POSIX::ctime($validite)));
+ }
+ print " Memo: '$memo'\n";
+ }
+ return 0;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Check the validity of a password
+# (Note: never send back a password with login-server!! security of passwords)
+sub checkaccount() {
+ my($userid, $passwd) = @_;
+ if ($userid eq "") {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un nom de compte svp.\n";
+ print "<exemple> check testname motdepasse\n";
+ } else {
+ print "Please input an account name.\n";
+ print "<example> check testname password\n";
+ }
+ return 136;
+ }
+ if (verify_accountname($userid) == 0) {
+ return 102;
+ }
+ if ($passwd eq "") {
+ return 134 if (($passwd = typepasswd()) eq "");
+ }
+ if (verify_password($passwd) == 0) {
+ return 131;
+ }
+ print $so pack("va24a24", 0x793a, $userid,$passwd);
+ $so->flush();
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x793b) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 132;
+ }
+ $buf = readso(28);
+ my($id2, $name) = unpack("Va24", $buf);
+ while (length($name) > 0 && substr($name, length($name)-1, 1) eq chr(0)) {
+ chop($name);
+ };
+ if ($id2 == -1 || $id2 == 4294967295) {
+ if ($defaultlanguage eq "F") {
+ print "Le compte [$userid] n'existe pas ou le mot de passe est incorrect.\n";
+ } else {
+ print "The account [$userid] doesn't exist or the password is incorrect.\n";
+ }
+ return 133;
+ } else {
+ if ($defaultlanguage eq "F") {
+ print "Le mot de passe donné correspond bien au compte [$name][id: $id2].\n";
+ } else {
+ print "The proposed password is correct for the account [$name][id: $id2].\n";
+ }
+ }
+ return 130;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Request to login-server to reload GM configuration file
+sub reloadGM() {
+ print $so pack("v", 0x7955);
+ $so->flush();
+ if ($defaultlanguage eq "F") {
+ print "Demande de recharger le fichier de configuration des GM envoyée.\n";
+ print "Vérifiez les comptes GM actuels (après rechargement):\n";
+ } else {
+ print "Request to reload the GM configuration file sended.\n";
+ print "Check the actual GM accounts (after reloading):\n";
+ }
+ &listaccount(0, 0, 1); # 1: to list only GM
+ return 180;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Send a broadcast message
+sub sendbroadcast() {
+ my($type, $message) = @_;
+ if ($message eq "" || length($message) == 0) {
+ if ($defaultlanguage eq "F") {
+ print "Entrez un message svp.\n";
+ if ($type == 0) {
+ print "<exemple> kami un message\n";
+ } else {
+ print "<exemple> kamib un message\n";
+ }
+ } else {
+ print "Please input a message.\n";
+ if ($type == 0) {
+ print "<example> kami a message\n";
+ } else {
+ print "<example> kamib a message\n";
+ }
+ }
+ return 136;
+ }
+
+ print $so pack("vvVa".length($message), 0x794e, $type, length($message), $message);
+ $so->flush();
+ $buf = readso(2);
+ if (unpack("v", $buf) != 0x794f) {
+ if ($defaultlanguage eq "F") {
+ print "Problème de connexion au serveur (réponse incorrecte).\n";
+ } else {
+ print "Connection error to the server (incorrect answer).\n";
+ }
+ return 152;
+ }
+ $buf = readso(2);
+ my($answer) = unpack("v", $buf);
+ if ($answer == -1 || $answer == 65535) {
+ if ($defaultlanguage eq "F") {
+ print "Echec de l'envoi du message. Aucun server de char en ligne.\n";
+ } else {
+ print "Message sending failed. No online char-server.\n";
+ }
+ } else {
+ if ($defaultlanguage eq "F") {
+ print "Message transmis au server de logins avec succès.\n";
+ } else {
+ print "Message successfully sended to login-server.\n";
+ }
+ }
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Change language of displaying
+sub changelanguage() {
+ my($language) = @_;
+ if ($language eq "" || length($language) == 0) {
+ if ($defaultlanguage == 'F') {
+ printf("Entrez une langue svp.\n");
+ printf("<exemple> language english\n");
+ printf(" language français\n");
+ } else {
+ printf("Please input a language.\n");
+ printf("<example> language english\n");
+ printf(" language français\n");
+ }
+ return 136;
+ }
+
+ $language = uc(substr($language, 0, 1));
+ if ($language =~ /^[EF]$/) {
+ $defaultlanguage = $language;
+ if ($defaultlanguage == 'F') {
+ printf("Changement de la langue d'affichage en Français.\n");
+ } else {
+ printf("Displaying language changed to English.\n");
+ }
+ } else {
+ if ($defaultlanguage == 'F') {
+ printf("Langue non paramétrée (langues possibles: 'Français' ou 'English').\n");
+ } else {
+ printf("Undefined language (possible languages: Français or English).\n");
+ }
+ }
+
+ return 0;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: sending 'end of connection' packet
+sub quit() {
+ print $so pack("v", 0x7532);
+ $so->flush();
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Get datas from the socket
+sub readso() {
+ my($len) = shift;
+ my($buf);
+ if (read($so, $buf, $len) < $len) {
+ if ($defaultlanguage eq "F") {
+ print "Erreur de lecture sur la Socket.\n";
+ } else {
+ print "Socket read error.\n";
+ }
+ exit(3);
+ }
+ return $buf;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Input of a password
+sub typepasswd {
+ my($passwd1, $passwd2);
+ cbreak();
+ if ($defaultlanguage eq "F") {
+ print "Entrez le mot de passe > "; $passwd1 = <STDIN>; chomp($passwd1); print "\n";
+ print "Ré-entrez le mot de passe > "; $passwd2 = <STDIN>; chomp($passwd2); print "\n";
+ } else {
+ print "Type the password > "; $passwd1 = <STDIN>; chomp($passwd1); print "\n";
+ print "Verify the password > "; $passwd2 = <STDIN>; chomp($passwd2); print "\n";
+ }
+ cooked();
+ if ($passwd1 ne $passwd2) {
+ if ($defaultlanguage eq "F") {
+ print "Erreur de vérification du mot de passe: Saisissez le même mot de passe svp.\n";
+ } else {
+ print "Password verification failed. Please input same password.\n";
+ }
+ return "";
+ }
+ return $passwd1;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Return ordonal text of a number
+sub makeordinal {
+ my($c) = shift;
+ if ($defaultlanguage eq "F") {
+ if ($c < 1) {
+ return $c;
+ }
+ return $c.("er", "ème")[$c == 1 ? 0 : 1];
+ } else {
+ if ($c % 10 < 4 && $c % 10 != 0 && ($c < 10 || $c > 20)) {
+ return $c.("st","nd","rd")[$c % 10 - 1];
+ }
+ return $c."th";
+ }
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Test of the validity of an account name (return 0 if incorrect, and 1 if ok)
+sub verify_accountname {
+ my($account_name) = @_; # Get the account_name
+ if ($account_name =~ /[\x00-\x1f]/) { # remove control char
+ my($c) = length($`) + 1;
+ if ($defaultlanguage eq "F") {
+ print "Caractère interdit trouvé dans le nom du compte (".makeordinal($c)." caractère).\n";
+ } else {
+ print "Illegal character found in the account name (".makeordinal($c)." character).\n";
+ }
+ return 0;
+ }
+ if (length($account_name) < 4) {
+ if ($defaultlanguage eq "F") {
+ print "Nom du compte trop court. Entrez un nom de compte de 4-23 caractères.\n";
+ } else {
+ print "Account name is too short. Please input an account name of 4-23 bytes.\n";
+ }
+ return 0;
+ }
+ if (length($account_name) > 23) {
+ if ($defaultlanguage eq "F") {
+ print "Nom du compte trop long. Entrez un nom de compte de 4-23 caractères.\n";
+ } else {
+ print "Account name is too long. Please input an account name of 4-23 bytes.\n";
+ }
+ return 0;
+ }
+ return 1;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Test of the validity of password (return 0 if incorrect, and 1 if ok)
+sub verify_password {
+ my($password) = @_; # Get the password
+ if ($password =~ /[\x00-\x1f]/) {
+ my($c) = length($`) + 1;
+ if ($defaultlanguage eq "F") {
+ print "Caractère interdit trouvé dans le mot de passe (".makeordinal($c)." caractère).\n";
+ } else {
+ print "Illegal character found in the password (".makeordinal($c)." character).\n";
+ }
+ return 0;
+ }
+ if (length($password) < 4) {
+ if ($defaultlanguage eq "F") {
+ print "Mot de passe trop court. Entrez un mot de passe de 4-23 caractères.\n";
+ } else {
+ print "Password is too short. Please input a password of 4-23 bytes.\n";
+ }
+ return 0;
+ }
+ if (length($password) > 23) {
+ if ($defaultlanguage eq "F") {
+ print "Mot de passe trop long. Entrez un mot de passe de 4-23 caractères.\n";
+ } else {
+ print "Password is too long. Please input a password of 4-23 bytes.\n";
+ }
+ return 0;
+ }
+ return 1;
+}
+
+#--------------------------------------------------------------------------
+
+# Sub-function: Test of the validity of an e-mail (return 0 if incorrect, and 1 if ok)
+sub verify_email {
+ my($email) = @_; # Get the e-mail
+ # To ignore a '.' before the @ (wanadoo, a provider, do that)
+ $email =~ s/\.\@/\@/;
+ # If the e-mail is void, it's not correct -> return 0
+ if ($email eq '') {
+ return(0);
+ }
+ # If the e-mail have no "@", it's not correct -> return 0
+ if ($email !~ /\@/) {
+ return(0);
+ }
+ # If the e-mail have a ",", a space, a tab or a ";", it's not correct -> return 0
+ if ($email =~ /[\,|\s|\;]/) {
+ return(0)
+ };
+ # IF
+ # (the e-mail contains 2 "@", or ".." or "@." or starts or finishes by a ".")
+ # OR IF
+ # (the e-mail doesn't contain "@localhost" AND
+ # - it doesn't contain characters followed by "@" itself followed by letters itself followed by "." and 2 or more letters
+ # - or an IP address)
+ # -> so, it's not good ! (finish !)
+ if ($email =~ /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)|(\.$)/ ||
+ ($email !~ /^.+\@localhost$/ &&
+ $email !~ /^.+\@\[?(\w|[-.])+\.[a-zA-Z]{2,3}|[0-9]{1,3}\]?$/)) {
+ return(0); # non-valid email
+ } else {
+ # If not, the e-email address is correct
+ return(1); # valid email
+ }
+} \ No newline at end of file
diff --git a/src/tool/mapcheck.sh b/src/tool/mapcheck.sh
new file mode 100644
index 000000000..337884c43
--- /dev/null
+++ b/src/tool/mapcheck.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+echo "============================================"
+echo "= map server status checker... ="
+echo "============================================"
+./map-server.exe &
+sleep 40
+
+while [ 0 ]
+do
+ pcpu=` top -n 1| grep map-server | awk '{print $9}' | awk 'BEGIN{FS="."} {print $1}' `
+ if [ "$pcpu" -gt 80 ];then
+ echo "============================================"
+ echo "map server is more than 80% (now $pcpu%)"
+ echo "============================================"
+ ppid=` ps -a | grep map-server | awk '{print $1}' `
+ kill $ppid
+ ./map-server.exe &
+ sleep 40
+ else
+ pmapct=` ps -a| grep map-server | wc -l `
+ if [ "$pmapct" -eq 0 ];then
+ echo "============================================"
+ echo "map server is not running..."
+ echo "restart map server..."
+ echo "============================================"
+ ./map-server.exe &
+ sleep 40
+ #echo "test"
+ else
+ echo "map server is ok (now $pcpu%)..."
+ sleep 5
+ fi
+ fi
+done \ No newline at end of file
diff --git a/src/tool/mapchecker.sh b/src/tool/mapchecker.sh
new file mode 100644
index 000000000..7250c342e
--- /dev/null
+++ b/src/tool/mapchecker.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+
+athena_dir="/home/athena/658/"
+
+while [ true ] ; do
+
+if [ ` ps fauxw | grep map-server | grep -v grep | wc -l ` -eq 0 ];then
+ #echo `date` " -- map-server crashed - restarting"
+ echo `date` " -- map-server crashed - restarting" >> /var/log/athena_status.log
+ killall -9 map-server
+ cd $athena_dir
+ nohup ./map-server ./conf/map_athena.conf ./inter_athena.conf &
+ sleep 240
+ #sleep 40 #for fast pc's remove the "#" at the beginning of the line and delete the line above
+fi
+
+
+if [ ` ps fauxw | grep map-server | grep -v grep | awk '{print $3}' | awk 'BEGIN{FS="."} {print $1}' ` -gt 10 ];then
+ #echo `date` " -- mapserver cpuload over 10 - restarting"
+ echo `date` " -- mapserver cpuload over 10 - restarting" >> /var/log/athena_status.log
+ killall -9 map-server
+ cd $athena_dir
+ nohup ./map-server ./conf/map_athena.conf ./inter_athena.conf &
+ sleep 240
+ #sleep 40 #for fast pc's remove the "#" at the beginning of the line and delete the line above
+ #echo `date` " -- restarted"
+ echo `date` " -- restarted" >> /var/log/athena_status.log
+fi
+
+if [ ` ps fauxw | grep char-server | grep -v grep | wc -l ` -eq 0 ];then
+ #echo `date` " -- char server crashed - restarting"
+ echo `date` " -- char server crashed - restarting" >> /var/log/athena_status.log
+ killall -9 char-server
+ cd $athena_dir
+ nohup ./char-server ./conf/char_athena.conf ./conf/inter_athena.conf &
+ #echo `date` " -- restarted"
+ echo `date` " -- restarted" >> /var/log/athena_status.log
+
+fi
+
+if [ ` ps fauxw | grep login-server | grep -v grep | wc -l ` -eq 0 ];then
+ #echo `date` " -- login server crashed - restarting"
+ echo `date` " -- login server crashed - restarting" >> /var/log/athena_status.log
+ killall -9 login-server
+ cd $athena_dir
+ nohup ./login-server ./conf/login_athena.conf &
+ #echo `date` " -- restarted"
+ echo `date` " -- restarted" >> /var/log/athena_status.log
+
+fi
+
+
+#echo `date` " -- everything is fine"
+echo `date` " -- everything is fine" >> /var/log/athena_status.log
+sleep 30
+done
diff --git a/src/txt-converter/char/GNUmakefile b/src/txt-converter/char/GNUmakefile
deleted file mode 100644
index 56723ca5a..000000000
--- a/src/txt-converter/char/GNUmakefile
+++ /dev/null
@@ -1,13 +0,0 @@
-all: char-converter
-sql: char-converter
-
-COMMON_OBJ = ../../common/core.o ../../common/socket.o ../../common/timer.o ../../common/db.o ../../common/malloc.o
-
-char-converter: char-converter.o strlib.o $(COMMON_OBJ)
- $(CC) -o ../../../$@ $^ $(LIB_S)
-
-char-converter.o: char-converter.c char.h strlib.h
-strlib.o: strlib.c strlib.h
-clean:
- rm -f *.o ../../../char-converter
-
diff --git a/src/txt-converter/char/Makefile b/src/txt-converter/char/Makefile
index 56723ca5a..6b85a04db 100644
--- a/src/txt-converter/char/Makefile
+++ b/src/txt-converter/char/Makefile
@@ -1,13 +1,13 @@
all: char-converter
sql: char-converter
-COMMON_OBJ = ../../common/core.o ../../common/socket.o ../../common/timer.o ../../common/db.o ../../common/malloc.o
+COMMON_OBJ = ../../common/obj/core.o ../../common/obj/socket.o ../../common/obj/timer.o ../../common/obj/grfio.o ../../common/obj/db.o ../../common/obj/lock.o ../../common/obj/nullpo.o ../../common/obj/malloc.o ../../common/obj/showmsg.o ../../common/obj/strlib.o
-char-converter: char-converter.o strlib.o $(COMMON_OBJ)
+char-converter: char-converter.o $(COMMON_OBJ)
$(CC) -o ../../../$@ $^ $(LIB_S)
-char-converter.o: char-converter.c char.h strlib.h
-strlib.o: strlib.c strlib.h
+char-converter.o: char-converter.c char.h ../../common/strlib.h
+strlib.o: strlib.c ../../common/strlib.h
clean:
rm -f *.o ../../../char-converter
diff --git a/src/txt-converter/char/char-converter.c b/src/txt-converter/char/char-converter.c
index 8928e240f..217bf2b15 100644
--- a/src/txt-converter/char/char-converter.c
+++ b/src/txt-converter/char/char-converter.c
@@ -16,16 +16,16 @@
#define STORAGE_MEMINC 16
-
+
#include "char.h"
-#include "strlib.h"
+#include "../../common/strlib.h"
#ifdef MEMWATCH
#include "memwatch.h"
#endif
-
+
char pet_txt[256]="save/pet.txt";
-char storage_txt[256]="save/storage.txt";
+char storage_txt[256]="save/storage.txt";
MYSQL mysql_handle;
MYSQL_RES* sql_res ;
@@ -39,7 +39,7 @@ char db_server_id[32] = "ragnarok";
char db_server_pw[32] = "ragnarok";
char db_server_logindb[32] = "ragnarok";
-struct storage *storage=NULL;
+struct storage *storage_=NULL;
struct mmo_map_server server[MAX_MAP_SERVERS];
int server_fd[MAX_MAP_SERVERS];
@@ -89,18 +89,18 @@ int inter_pet_fromstr(char *str, struct s_pet *p)
int s;
int tmp_int[16];
char tmp_str[256];
-
+
memset(p, 0, sizeof(struct s_pet));
-
+
// printf("sscanf pet main info\n");
s=sscanf(str,"%d, %d,%[^\t]\t%d, %d, %d, %d, %d, %d, %d, %d, %d", &tmp_int[0], &tmp_int[1], tmp_str, &tmp_int[2],
&tmp_int[3], &tmp_int[4], &tmp_int[5], &tmp_int[6], &tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10]);
if(s!=12)
return 1;
-
+
p->pet_id = tmp_int[0];
- p->class = tmp_int[1];
+ p->class_ = tmp_int[1];
memcpy(p->name, tmp_str, 24);
p->account_id = tmp_int[2];
p->char_id = tmp_int[3];
@@ -126,11 +126,11 @@ int inter_pet_fromstr(char *str, struct s_pet *p)
//---------------------------------------------------------
int inter_pet_tosql(int pet_id, struct s_pet *p) {
//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`)
-
+
char tmp_sql[65535];
MYSQL_RES* sql_res ;
MYSQL_ROW sql_row ;
-
+
jstrescapecpy (t_name, p->name);
if(p->hungry < 0)
p->hungry = 0;
@@ -148,19 +148,19 @@ int inter_pet_tosql(int pet_id, struct s_pet *p) {
sql_row = mysql_fetch_row(sql_res); //row fetching
if (!sql_row) //no row -> insert
sprintf(tmp_sql,"INSERT INTO `pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`) VALUES ('%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
- p->pet_id, p->class, t_name, p->account_id, p->char_id, p->level, p->egg_id,
+ p->pet_id, p->class_, t_name, p->account_id, p->char_id, p->level, p->egg_id,
p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate);
else //row reside -> updating
sprintf(tmp_sql, "UPDATE `pet` SET `class`='%d',`name`='%s',`account_id`='%d',`char_id`='%d',`level`='%d',`egg_id`='%d',`equip`='%d',`intimate`='%d',`hungry`='%d',`rename_flag`='%d',`incuvate`='%d' WHERE `pet_id`='%d'",
- p->class, t_name, p->account_id, p->char_id, p->level, p->egg_id,
+ p->class_, t_name, p->account_id, p->char_id, p->level, p->egg_id,
p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate, p->pet_id);
mysql_free_result(sql_res) ; //resource free
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
}
-
+
printf ("pet dump success! - %d:%s\n", pet_id, p->name);
-
+
return 0;
}
@@ -168,27 +168,27 @@ int storage_tosql(int account_id,struct storage *p){
// id -> DB dump
// storage {`account_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`}
int i,j;
-
+
j=0;
-
+
//printf ("starting storage dump to DB - id: %d\n", account_id);
-
+
//delete old data.
sprintf(tmp_sql,"DELETE FROM `storage` WHERE `account_id`='%d'",account_id);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
}
-
+
//printf ("all storage item was deleted ok\n");
-
+
for(i=0;i<MAX_STORAGE;i++) {
- //printf ("save storage num: %d (%d:%d)\n",i, p->storage[i].nameid , p->storage[i].amount);
-
- if( (p->storage[i].nameid) && (p->storage[i].amount) ){
+ //printf ("save storage num: %d (%d:%d)\n",i, p->storage_[i].nameid , p->storage_[i].amount);
+
+ if( (p->storage_[i].nameid) && (p->storage_[i].amount) ){
sprintf(tmp_sql,"INSERT INTO `storage` (`account_id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`card0`,`card1`,`card2`,`card3`,`broken`) VALUES ('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
- p->account_id, p->storage[i].nameid, p->storage[i].amount, p->storage[i].equip,
- p->storage[i].identify, p->storage[i].refine, p->storage[i].attribute,
- p->storage[i].card[0], p->storage[i].card[1], p->storage[i].card[2], p->storage[i].card[3], p->storage[i].broken );
+ p->account_id, p->storage_[i].nameid, p->storage_[i].amount, p->storage_[i].equip,
+ p->storage_[i].identify, p->storage_[i].refine, p->storage_[i].attribute,
+ p->storage_[i].card[0], p->storage_[i].card[1], p->storage_[i].card[2], p->storage_[i].card[3], p->storage_[i].broken );
//printf ("%s\n",tmp_sql);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error - %s\n", mysql_error(&mysql_handle) );
@@ -212,51 +212,51 @@ int storage_fromstr(char *str, struct storage *p)
if(set!=2)
return 0;
if(str[next]=='\n' || str[next]=='\r')
- return 1;
+ return 1;
next++;
for(i=0;str[next] && str[next]!='\t';i++){
if(sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
&tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
&tmp_int[4], &tmp_int[5], &tmp_int[6],
&tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10], &tmp_int[11], &len) == 12) {
- p->storage[i].id = tmp_int[0];
- p->storage[i].nameid = tmp_int[1];
- p->storage[i].amount = tmp_int[2];
- p->storage[i].equip = tmp_int[3];
- p->storage[i].identify = tmp_int[4];
- p->storage[i].refine = tmp_int[5];
- p->storage[i].attribute = tmp_int[6];
- p->storage[i].card[0] = tmp_int[7];
- p->storage[i].card[1] = tmp_int[8];
- p->storage[i].card[2] = tmp_int[9];
- p->storage[i].card[3] = tmp_int[10];
- p->storage[i].broken = tmp_int[11];
+ p->storage_[i].id = tmp_int[0];
+ p->storage_[i].nameid = tmp_int[1];
+ p->storage_[i].amount = tmp_int[2];
+ p->storage_[i].equip = tmp_int[3];
+ p->storage_[i].identify = tmp_int[4];
+ p->storage_[i].refine = tmp_int[5];
+ p->storage_[i].attribute = tmp_int[6];
+ p->storage_[i].card[0] = tmp_int[7];
+ p->storage_[i].card[1] = tmp_int[8];
+ p->storage_[i].card[2] = tmp_int[9];
+ p->storage_[i].card[3] = tmp_int[10];
+ p->storage_[i].broken = tmp_int[11];
next += len;
if (str[next] == ' ')
- next++;
+ next++;
}
else if(sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
&tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
&tmp_int[4], &tmp_int[5], &tmp_int[6],
&tmp_int[7], &tmp_int[8], &tmp_int[9], &tmp_int[10], &len) == 11) {
- p->storage[i].id = tmp_int[0];
- p->storage[i].nameid = tmp_int[1];
- p->storage[i].amount = tmp_int[2];
- p->storage[i].equip = tmp_int[3];
- p->storage[i].identify = tmp_int[4];
- p->storage[i].refine = tmp_int[5];
- p->storage[i].attribute = tmp_int[6];
- p->storage[i].card[0] = tmp_int[7];
- p->storage[i].card[1] = tmp_int[8];
- p->storage[i].card[2] = tmp_int[9];
- p->storage[i].card[3] = tmp_int[10];
- p->storage[i].broken = 0;
+ p->storage_[i].id = tmp_int[0];
+ p->storage_[i].nameid = tmp_int[1];
+ p->storage_[i].amount = tmp_int[2];
+ p->storage_[i].equip = tmp_int[3];
+ p->storage_[i].identify = tmp_int[4];
+ p->storage_[i].refine = tmp_int[5];
+ p->storage_[i].attribute = tmp_int[6];
+ p->storage_[i].card[0] = tmp_int[7];
+ p->storage_[i].card[1] = tmp_int[8];
+ p->storage_[i].card[2] = tmp_int[9];
+ p->storage_[i].card[3] = tmp_int[10];
+ p->storage_[i].broken = 0;
next += len;
if (str[next] == ' ')
- next++;
+ next++;
}
-
+
else return 0;
}
return 1;
@@ -337,7 +337,7 @@ int mmo_char_fromstr(char *str, struct mmo_charstatus *p) {
p->char_id = tmp_int[0];
p->account_id = tmp_int[1];
p->char_num = tmp_int[2];
- p->class = tmp_int[3];
+ p->class_ = tmp_int[3];
p->base_level = tmp_int[4];
p->job_level = tmp_int[5];
p->base_exp = tmp_int[6];
@@ -508,10 +508,10 @@ int mmo_char_fromstr(char *str, struct mmo_charstatus *p) {
//==========================================================================================================
int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
int i,save_flag;
-
+
save_flag = char_id;
printf("request save char data... (%d)\n",char_id);
-
+
//`char`( `char_id`,`account_id`,`char_num`,`name`,`class`,`base_level`,`job_level`,`base_exp`,`job_exp`,`zeny`, //9
//`str`,`agi`,`vit`,`int`,`dex`,`luk`, //15
//`max_hp`,`hp`,`max_sp`,`sp`,`status_point`,`skill_point`, //21
@@ -525,7 +525,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
"`option`='%d',`karma`='%d',`manner`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d',"
"`hair`='%d',`hair_color`='%d',`clothes_color`='%d',`weapon`='%d',`shield`='%d',`head_top`='%d',`head_mid`='%d',`head_bottom`='%d',"
"`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d', `partner_id` = '%d'",
- char_id,p->account_id,p->char_num,p->name,p->class, p->base_level, p->job_level,
+ char_id,p->account_id,p->char_num,p->name,p->class_, p->base_level, p->job_level,
p->base_exp, p->job_exp, p->zeny,
p->max_hp, p->hp, p->max_sp, p->sp, p->status_point, p->skill_point,
p->str, p->agi, p->vit, p->int_, p->dex, p->luk,
@@ -535,17 +535,17 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
p->last_point.map, p->last_point.x, p->last_point.y,
p->save_point.map, p->save_point.x, p->save_point.y, p->partner_id
);
-
+
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (update `char`)- %s\n", mysql_error(&mysql_handle) );
}
-
+
//`memo` (`memo_id`,`char_id`,`map`,`x`,`y`)
sprintf(tmp_sql,"DELETE FROM `memo` WHERE `char_id`='%d'",char_id);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (delete `memo`)- %s\n", mysql_error(&mysql_handle) );
}
-
+
//insert here.
for(i=0;i<10;i++){
if(p->memo_point[i].map[0]){
@@ -560,7 +560,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (delete `inventory`)- %s\n", mysql_error(&mysql_handle) );
}
-
+
//insert here.
for(i=0;i<MAX_INVENTORY;i++){
if(p->inventory[i].nameid){
@@ -579,7 +579,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (delete `cart_inventory`)- %s\n", mysql_error(&mysql_handle) );
}
-
+
//insert here.
for(i=0;i<MAX_CART;i++){
if(p->cart[i].nameid){
@@ -593,14 +593,14 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
}
}
}
-
-
+
+
//`skill` (`char_id`, `id`, `lv`)
sprintf(tmp_sql,"DELETE FROM `skill` WHERE `char_id`='%d'",char_id);
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (delete `skill`)- %s\n", mysql_error(&mysql_handle) );
}
-
+
//insert here.
for(i=0;i<MAX_SKILL;i++){
if(p->skill[i].id){
@@ -618,7 +618,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
if(mysql_query(&mysql_handle, tmp_sql) ) {
printf("DB server Error (delete `global_reg_value`)- %s\n", mysql_error(&mysql_handle) );
}
-
+
//insert here.
for(i=0;i<p->global_reg_num;i++){
if(p->global_reg[i].value !=0){
@@ -629,10 +629,10 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
}
}
}
-
+
printf("saving char is done... (%d)\n",char_id);
save_flag = 0;
-
+
return 0;
}
//==========================================================================================================
@@ -645,7 +645,7 @@ int mmo_char_init(void){
char input;
FILE *fp;
-
+
//DB connection initialized
mysql_init(&mysql_handle);
printf("Connect DB server.... (inter server)\n");
@@ -658,7 +658,7 @@ int mmo_char_init(void){
else {
printf ("connect success! (inter server)\n");
}
-
+
printf("Warning : Make sure you backup your databases before continuing!\n");
@@ -667,14 +667,14 @@ int mmo_char_init(void){
if(input == 'y' || input == 'Y'){
printf("\nConverting Character Database...\n");
fp=fopen("save/athena.txt","r");
- char_dat=malloc(sizeof(char_dat[0])*256);
+ char_dat = (struct mmo_charstatus*)malloc(sizeof(char_dat[0])*256);
char_max=256;
if(fp==NULL)
return 0;
while(fgets(line, 65535, fp)){
if(char_num>=char_max){
char_max+=256;
- char_dat=realloc(char_dat, sizeof(char_dat[0]) *char_max);
+ char_dat = (struct mmo_charstatus*)realloc(char_dat, sizeof(char_dat[0]) *char_max);
}
memset(&char_dat[char_num], 0, sizeof(char_dat[0]));
ret=mmo_char_fromstr(line, &char_dat[char_num]);
@@ -689,8 +689,8 @@ int mmo_char_init(void){
printf("char data convert end\n");
fclose(fp);
}
-
- while(getchar() != '\n');
+
+ while(getchar() != '\n');
printf("\nDo you wish to convert your Storage Database to SQL? (y/n) : ");
input=getchar();
if(input == 'y' || input == 'Y') {
@@ -700,25 +700,25 @@ int mmo_char_init(void){
printf("cant't read : %s\n",storage_txt);
return 0;
}
-
+
while(fgets(line,65535,fp)){
set=sscanf(line,"%d,%d",&tmp_int[0],&tmp_int[1]);
if(set==2) {
if(i==0){
- storage=malloc(sizeof(struct storage));
+ storage_ = (struct storage*)malloc(sizeof(struct storage));
}else{
- storage=realloc(storage,sizeof(struct storage)*(i+1));
+ storage_ = (struct storage*)realloc(storage_,sizeof(struct storage)*(i+1));
}
- memset(&storage[i],0,sizeof(struct storage));
- storage[i].account_id=tmp_int[0];
- storage_fromstr(line,&storage[i]);
- storage_tosql(tmp_int[0],&storage[i]); //to sql. (dump)
+ memset(&storage_[i],0,sizeof(struct storage));
+ storage_[i].account_id=tmp_int[0];
+ storage_fromstr(line,&storage_[i]);
+ storage_tosql(tmp_int[0],&storage_[i]); //to sql. (dump)
i++;
}
}
fclose(fp);
}
-
+
while(getchar() != '\n');
printf("\nDo you wish to convert your Pet Database to SQL? (y/n) : ");
input=getchar();
@@ -726,8 +726,8 @@ int mmo_char_init(void){
printf("\nConverting Pet Database...\n");
if( (fp=fopen(pet_txt,"r")) ==NULL )
return 1;
-
- p=malloc(sizeof(struct s_pet));
+
+ p = (struct s_pet*)malloc(sizeof(struct s_pet));
while(fgets(line, sizeof(line), fp)){
if(p==NULL){
printf("int_pet: out of memory!\n");
@@ -789,10 +789,13 @@ int inter_config_read(const char *cfgName) {
else if(strcmpi(w1,"db_server_logindb")==0){
strcpy(db_server_logindb, w2);
printf ("set db_server_logindb : %s\n",w2);
+ //support the import command, just like any other config
+ }else if(strcmpi(w1,"import")==0){
+ inter_config_read(w2);
}
}
fclose(fp);
-
+
printf("Reading interserver configuration: Done\n");
return 0;
@@ -825,7 +828,7 @@ int char_config_read(const char *cfgName) {
}
fclose(fp);
printf("Reading configuration: Done\n");
-
+
return 0;
}
diff --git a/src/txt-converter/char/char.h b/src/txt-converter/char/char.h
index b5864b31c..e1d5c90dc 100644
--- a/src/txt-converter/char/char.h
+++ b/src/txt-converter/char/char.h
@@ -24,9 +24,9 @@ struct mmo_map_server{
char map[MAX_MAP_PER_SERVER][16];
};
-int mapif_sendall(unsigned char *buf,unsigned int len);
-int mapif_sendallwos(int fd,unsigned char *buf,unsigned int len);
-int mapif_send(int fd,unsigned char *buf,unsigned int len);
+int mapif_sendall(char *buf,unsigned int len);
+int mapif_sendallwos(int fd,char *buf,unsigned int len);
+int mapif_send(int fd,char *buf,unsigned int len);
extern int autosave_interval;
diff --git a/src/txt-converter/char/strlib.c b/src/txt-converter/char/strlib.c
deleted file mode 100644
index 60803c1d1..000000000
--- a/src/txt-converter/char/strlib.c
+++ /dev/null
@@ -1,66 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "strlib.h"
-
-//-----------------------------------------------
-// string lib.
-unsigned char* jstrescape (unsigned char* pt) {
- //copy from here
- unsigned char * ptr;
- int i =0, j=0;
-
- //copy string to temporary
- ptr = malloc(J_MAX_MALLOC_SIZE);
- strcpy (ptr,pt);
-
- while (ptr[i] != '\0') {
- switch (ptr[i]) {
- case '\'':
- pt[j++] = '\\';
- pt[j++] = ptr[i++];
- break;
- default:
- pt[j++] = ptr[i++];
- }
- }
- pt[j++] = '\0';
- free (ptr);
- return (unsigned char*) &pt[0];
-}
-
-unsigned char* jstrescapecpy (unsigned char* pt,unsigned char* spt) {
- //copy from here
- int i =0, j=0;
-
- while (spt[i] != '\0') {
- switch (spt[i]) {
- case '\'':
- pt[j++] = '\\';
- pt[j++] = spt[i++];
- break;
- default:
- pt[j++] = spt[i++];
- }
- }
- pt[j++] = '\0';
- return (unsigned char*) &pt[0];
-}
-int jmemescapecpy (unsigned char* pt,unsigned char* spt, int size) {
- //copy from here
- int i =0, j=0;
-
- while (i < size) {
- switch (spt[i]) {
- case '\'':
- pt[j++] = '\\';
- pt[j++] = spt[i++];
- break;
- default:
- pt[j++] = spt[i++];
- }
- }
- // copy size is 0 ~ (j-1)
- return j;
-}
diff --git a/src/txt-converter/char/strlib.h b/src/txt-converter/char/strlib.h
deleted file mode 100644
index 442cfac29..000000000
--- a/src/txt-converter/char/strlib.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _J_STR_H_
-#define _J_STR_H_
-#define J_MAX_MALLOC_SIZE 65535
-//string functions.
-//code by Jioh L. Jung
-unsigned char* jstrescape (unsigned char* pt);
-unsigned char* jstrescapecpy (unsigned char* pt,unsigned char* spt);
-int jmemescapecpy (unsigned char* pt,unsigned char* spt, int size);
-#endif
diff --git a/src/txt-converter/common/mmo.h b/src/txt-converter/common/mmo.h
index 178046a17..28462e99d 100644
--- a/src/txt-converter/common/mmo.h
+++ b/src/txt-converter/common/mmo.h
@@ -29,11 +29,11 @@
#define MAX_STORAGE 300
#define MAX_GUILD_STORAGE 1000
#define MAX_PARTY 12
-#define MAX_GUILD 56 // increased max guild members to accomodate for +2 increase for extension levels [Valaris]
-#define MAX_GUILDPOSITION 56 // increased max guild positions to accomodate for all members [Valaris]
+#define MAX_GUILD 16+10*6 // increased max guild members to accomodate for +6 increase for extension levels [Lupus]
+#define MAX_GUILDPOSITION 20 // increased max guild positions to accomodate for all members [Valaris]
#define MAX_GUILDEXPLUSION 32
#define MAX_GUILDALLIANCE 16
-#define MAX_GUILDSKILL 8
+#define MAX_GUILDSKILL 15 // increased max guild skills because of new skills [Sara-chan]
#define MAX_GUILDCASTLE 24 // increased to include novice castles [Valaris]
#define MAX_GUILDLEVEL 50
@@ -87,7 +87,7 @@ struct s_pet {
int account_id;
int char_id;
int pet_id;
- short class;
+ short class_;
short level;
short egg_id;//pet egg id
short equip;//pet equip name_id
@@ -105,7 +105,7 @@ struct mmo_charstatus {
int base_exp,job_exp,zeny;
- short class;
+ short class_;
short status_point,skill_point;
int hp,max_hp,sp,max_sp;
short option,karma,manner;
@@ -135,14 +135,14 @@ struct storage {
int account_id;
short storage_status;
short storage_amount;
- struct item storage[MAX_STORAGE];
+ struct item storage_[MAX_STORAGE];
};
struct guild_storage {
int guild_id;
short storage_status;
short storage_amount;
- struct item storage[MAX_GUILD_STORAGE];
+ struct item storage_[MAX_GUILD_STORAGE];
};
struct map_session_data;
@@ -168,7 +168,7 @@ struct party {
struct guild_member {
int account_id, char_id;
- short hair,hair_color,gender,class,lv;
+ short hair,hair_color,gender,class_,lv;
int exp,exp_payper;
short online,position;
int rsv1,rsv2;
@@ -237,8 +237,8 @@ struct guild_castle {
int Ghp4;
int Ghp5;
int Ghp6;
- int Ghp7;
- int GID0;
+ int Ghp7;
+ int GID0;
int GID1;
int GID2;
int GID3;
diff --git a/src/txt-converter/login/GNUmakefile b/src/txt-converter/login/GNUmakefile
deleted file mode 100644
index 9f34e143a..000000000
--- a/src/txt-converter/login/GNUmakefile
+++ /dev/null
@@ -1,11 +0,0 @@
-all: login-converter
-sql: login-converter
-
-COMMON_OBJ = ../../common/core.o ../../common/socket.o ../../common/timer.o ../../common/db.o ../../common/malloc.o
-COMMON_H = ../../common/core.h ../../common/socket.h ../../common/timer.h ../../common/mmo.h ../../common/version.h ../../common/db.h ../../common/malloc.h
-
-login-converter: login-converter.o ../../login_sql/md5calc.o ../../login_sql/strlib.o $(COMMON_OBJ)
- $(CC) -o ../../../$@ $^ $(LIB_S)
-login-converter.o: login-converter.c ../../login_sql/login.h ../../login_sql/md5calc.h ../../login_sql/strlib.h $(COMMON_H)
-clean:
- rm -f *.o ../../../login-converter
diff --git a/src/txt-converter/login/Makefile b/src/txt-converter/login/Makefile
index 9f34e143a..7158931d0 100644
--- a/src/txt-converter/login/Makefile
+++ b/src/txt-converter/login/Makefile
@@ -1,11 +1,12 @@
all: login-converter
sql: login-converter
-COMMON_OBJ = ../../common/core.o ../../common/socket.o ../../common/timer.o ../../common/db.o ../../common/malloc.o
-COMMON_H = ../../common/core.h ../../common/socket.h ../../common/timer.h ../../common/mmo.h ../../common/version.h ../../common/db.h ../../common/malloc.h
+COMMON_OBJ = ../../common/obj/core.o ../../common/obj/socket.o ../../common/obj/timer.o ../../common/obj/grfio.o ../../common/obj/db.o ../../common/obj/lock.o ../../common/obj/nullpo.o ../../common/obj/malloc.o ../../common/obj/showmsg.o ../../common/obj/strlib.o
-login-converter: login-converter.o ../../login_sql/md5calc.o ../../login_sql/strlib.o $(COMMON_OBJ)
+COMMON_H = ../../common/core.h ../../common/socket.h ../../common/timer.h ../../common/mmo.h ../../common/version.h ../../common/db.h ../../common/malloc.h ../../common/strlib.h
+
+login-converter: login-converter.o ../../login_sql/md5calc.o $(COMMON_OBJ)
$(CC) -o ../../../$@ $^ $(LIB_S)
-login-converter.o: login-converter.c ../../login_sql/login.h ../../login_sql/md5calc.h ../../login_sql/strlib.h $(COMMON_H)
+login-converter.o: login-converter.c ../../login_sql/login.h ../../login_sql/md5calc.h $(COMMON_H)
clean:
rm -f *.o ../../../login-converter
diff --git a/src/txt-converter/login/login-converter.c b/src/txt-converter/login/login-converter.c
index a277ca949..d301e8db3 100644
--- a/src/txt-converter/login/login-converter.c
+++ b/src/txt-converter/login/login-converter.c
@@ -40,7 +40,7 @@ struct {
int sex,delflag;
} auth_fifo[AUTH_FIFO_SIZE];
int auth_fifo_pos=0;
-struct {
+struct auth_dat_ {
int account_id, sex;
char userid[24], pass[24], lastlogin[24];
int logincount;
@@ -72,7 +72,7 @@ char db_server_logindb[32] = "ragnarok";
int isGM(int account_id)
{
struct gm_account *p;
- p = numdb_search(gm_account_db,account_id);
+ p = (struct gm_account*)numdb_search(gm_account_db,account_id);
if( p == NULL)
return 0;
return p->level;
@@ -95,7 +95,7 @@ int read_gm_account()
if(line[0] == '/' || line[1] == '/' || line[2] == '/')
continue;
- p=malloc(sizeof(struct gm_account));
+ p = (struct gm_account*)malloc(sizeof(struct gm_account));
if(p==NULL){
printf("gm_account: out of memory!\n");
exit(0);
@@ -145,7 +145,7 @@ int mmo_auth_init(void)
fp=fopen("save/account.txt","r");
- auth_dat=malloc(sizeof(auth_dat[0])*256);
+ auth_dat = (struct auth_dat_*)malloc(sizeof(auth_dat[0])*256);
auth_max=256;
if(fp==NULL)
return 0;
@@ -234,6 +234,10 @@ int login_config_read(const char *cfgName){
strcpy(db_server_logindb, w2);
printf ("set db_server_logindb : %s\n",w2);
}
+ //support the import command, just like any other config
+ else if(strcmpi(w1,"import")==0){
+ login_config_read(w2);
+ }
}
fclose(fp);
printf ("End reading interserver configuration...\n");
diff --git a/src/webserver/Changelog.txt b/src/webserver/Changelog.txt
deleted file mode 100644
index e4d38bac0..000000000
--- a/src/webserver/Changelog.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Date Added
-12/3
- * Creation of eAthena Web Server v2 [MC Cameri] \ No newline at end of file
diff --git a/src/webserver/Makefile b/src/webserver/Makefile
index 000754036..077b39980 100644
--- a/src/webserver/Makefile
+++ b/src/webserver/Makefile
@@ -1,32 +1,20 @@
-CC = gcc -pipe
-MAKE = make
-OPT = -g -O2 -ffast-math
-
-ifeq ($(findstring CYGWIN,$(PLATFORM)), CYGWIN)
-CFLAGS = $(OPT) -Wall -I../common
-else
-CFLAGS = $(OPT) -Wall -I../common
-endif
-
-OBJ = main.o webserver.o ../common/showmsg.o
-LINKOBJ = main.o webserver.o ../common/showmsg.o
-
-all: clean webserver run
+all:
+ #Generate framework...
+ $(CC) -c parse.c
+ $(CC) -c generate.c
+ $(CC) -c htmlstyle.c
+ $(CC) -c logs.c
+
+ #Generate "pages"...
+ cd pages && $(CC) -c about.c && cd ..
+ cd pages && $(CC) -c sample.c && cd ..
+ cd pages && $(CC) -c notdone.c && cd ..
+
+ #Building the server...
+ $(CC) -o webserver main.c parse.o generate.o htmlstyle.o \
+ logs.o pages/about.o pages/sample.o pages/notdone.o
clean:
- rm -f *.o webserver.exe ../common/showmsg.o
-
-webserver: main.o webserver.o ../common/showmsg.o
- $(CC) $(OPT) -o "Webserver.exe" $(OBJ)
-
-main.o: main.c
- $(CC) $(OPT) -c main.c -o main.o $(CFLAGS)
-
-webserver.o: webserver.c
- $(CC) $(OPT) -c webserver.c -o webserver.o $(CFLAGS)
-
-../common/showmsg.o: ../common/showmsg.c
- $(CC) $(OPT) -c ../common/showmsg.c -o ../common/showmsg.o $(CFLAGS)
-
-run:
- ./webserver
+ rm -f *.o
+ rm -f pages/*.o
+ rm -f webserver
diff --git a/src/webserver/Makefile.win b/src/webserver/Makefile.win
deleted file mode 100644
index 65cf676ad..000000000
--- a/src/webserver/Makefile.win
+++ /dev/null
@@ -1,35 +0,0 @@
-# Project: Webserver
-# Makefile created by Dev-C++ 4.9.8.0
-
-CPP = g++.exe -D__DEBUG__
-CC = gcc.exe -D__DEBUG__
-WINDRES = windres.exe
-RES =
-OBJ = main.o webserver.o ../common/showmsg.o $(RES)
-LINKOBJ = main.o webserver.o ../common/showmsg.o $(RES)
-LIBS = -L"C:/Program Files/Dev-Cpp/lib" -L"C:/cygwin/lib"
-INCS = -I"C:/Program Files/Dev-Cpp/include" -I"C:/cygwin/usr/include" -I"C:/cygwin/usr/include/mingw"
-CXXINCS = -I"C:/Program Files/Dev-Cpp/include/c++" -I"C:/Program Files/Dev-Cpp/include/c++/mingw32" -I"C:/Program Files/Dev-Cpp/include/c++/backward" -I"C:/Program Files/Dev-Cpp/include" -I"C:/cygwin/usr/include/c++/3.3.1"
-BIN = webserver.exe
-CXXFLAGS = $(CXXINCS) -pg -g3
-CFLAGS = $(INCS) -pg -g3
-
-.PHONY: all all-before all-after clean clean-custom
-
-all: all-before webserver.exe all-after
-
-
-clean: clean-custom
- rm -f $(OBJ) $(BIN)
-
-$(BIN): $(LINKOBJ)
- $(CC) $(LINKOBJ) -o "webserver.exe" $(LIBS)
-
-main.o: main.c
- $(CC) -c main.c -o main.o $(CFLAGS)
-
-webserver.o: webserver.c
- $(CC) -c webserver.c -o webserver.o $(CFLAGS)
-
-../common/showmsg.o: ../common/showmsg.c
- $(CC) -c ../common/showmsg.c -o ../common/showmsg.o $(CFLAGS)
diff --git a/src/webserver/WEBSER~1.layout b/src/webserver/WEBSER~1.layout
deleted file mode 100644
index 49854196f..000000000
--- a/src/webserver/WEBSER~1.layout
+++ /dev/null
@@ -1,24 +0,0 @@
-[Editors]
-Focused=-1
-Order=-1,0
-[Editor_0]
-Open=1
-Top=0
-CursorCol=5
-CursorRow=30
-TopLine=1
-LeftChar=1
-[Editor_1]
-Open=1
-Top=0
-CursorCol=1
-CursorRow=35
-TopLine=16
-LeftChar=1
-[Editor_2]
-Open=1
-Top=1
-CursorCol=14
-CursorRow=4
-TopLine=1
-LeftChar=1
diff --git a/src/webserver/Webserver.dev b/src/webserver/Webserver.dev
deleted file mode 100644
index 5bbb3a08c..000000000
--- a/src/webserver/Webserver.dev
+++ /dev/null
@@ -1,97 +0,0 @@
-[Project]
-FileName=Webserver.dev
-Name=Webserver
-UnitCount=5
-Type=1
-Ver=1
-ObjFiles=
-Includes=
-Libs=
-PrivateResource=
-ResourceIncludes=
-MakeIncludes=
-Compiler=
-CppCompiler=
-Linker=
-IsCpp=0
-Icon=
-ExeOutput=
-ObjectOutput=
-OverrideOutput=1
-OverrideOutputName=webserver.exe
-HostApplication=
-Folders=common
-CommandLine=
-IncludeVersionInfo=0
-SupportXPThemes=0
-CompilerSet=1
-CompilerSettings=000000000000000000
-
-[Unit1]
-FileName=main.c
-CompileCpp=0
-Folder=
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=$(CC) -c main.c -o main.o webserver.o $(CFLAGS)
-
-[VersionInfo]
-Major=0
-Minor=1
-Release=1
-Build=1
-LanguageID=1033
-CharsetID=1252
-CompanyName=
-FileVersion=
-FileDescription=Developed using the Dev-C++ IDE
-InternalName=
-LegalCopyright=
-LegalTrademarks=
-OriginalFilename=
-ProductName=
-ProductVersion=
-AutoIncBuildNr=0
-
-[Unit2]
-FileName=webserver.c
-CompileCpp=0
-Folder=
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=1
-BuildCmd=$(CC) -c webserver.c -o webserver.o $(CFLAGS)
-
-[Unit3]
-FileName=webserver.h
-CompileCpp=0
-Folder=
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=
-
-[Unit4]
-FileName=..\common\showmsg.c
-CompileCpp=0
-Folder=common
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=
-
-[Unit5]
-FileName=..\common\showmsg.h
-CompileCpp=0
-Folder=common
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=
-
diff --git a/src/webserver/Webserver.layout b/src/webserver/Webserver.layout
deleted file mode 100644
index b99312289..000000000
--- a/src/webserver/Webserver.layout
+++ /dev/null
@@ -1,38 +0,0 @@
-[Editors]
-Focused=0
-Order=0,2,1,-1
-[Editor_0]
-Open=1
-Top=1
-CursorCol=55
-CursorRow=128
-TopLine=95
-LeftChar=1
-[Editor_1]
-Open=1
-Top=0
-CursorCol=25
-CursorRow=113
-TopLine=92
-LeftChar=1
-[Editor_2]
-Open=1
-Top=0
-CursorCol=1
-CursorRow=21
-TopLine=1
-LeftChar=1
-[Editor_3]
-Open=0
-Top=0
-CursorCol=20
-CursorRow=2
-TopLine=1
-LeftChar=1
-[Editor_4]
-Open=0
-Top=0
-CursorCol=20
-CursorRow=1
-TopLine=1
-LeftChar=1
diff --git a/src/webserver/conf/webserver-athena.conf b/src/webserver/conf/webserver-athena.conf
deleted file mode 100644
index 6f84aa133..000000000
--- a/src/webserver/conf/webserver-athena.conf
+++ /dev/null
@@ -1,36 +0,0 @@
-#############################################################
-# ______ __ __ #
-# /\ _ \/\ \__/\ \ #
-# __\ \ \L\ \ \ ,_\ \ \___ __ ___ __ #
-# /'__`\ \ __ \ \ \/\ \ _ `\ /'__`\/' _ `\ /'__`\ #
-# /\ __/\ \ \/\ \ \ \_\ \ \ \ \/\ __//\ \/\ \/\ \L\.\_ #
-# \ \____\\ \_\ \_\ \__\\ \_\ \_\ \____\ \_\ \_\ \__/.\_\ #
-# \/____/ \/_/\/_/\/__/ \/_/\/_/\/____/\/_/\/_/\/__/\/_/ #
-# eAthena Web Server (Second Edition) #
-# by MC Cameri #
-# ------------------------------------------------------- #
-# -Website/Forum- #
-# http://eathena.deltaanime.net/ #
-# -Download URL- #
-# http://eathena.systeminplace.net/ #
-# -IRC Channel- #
-# irc://irc.deltaanime.net/#athena #
-#############################################################
-
-// Display the eAthena Logo at startup?
-show_title: 1
-
-//Web Server Port
-port: 81
-
-//Web Server Password
-password: juan16
-
-//Page Header
-header: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-//Document index
-document_index: index.xhtml
-
-//Send favorite icon if provided?
-favicon: yes
diff --git a/src/webserver/doc/API.txt b/src/webserver/doc/API.txt
new file mode 100644
index 000000000..c80f7bd44
--- /dev/null
+++ b/src/webserver/doc/API.txt
@@ -0,0 +1,50 @@
+Here's the webserver API, so you can work on the webserver.
+
+My personal goal is to make this interface simple, so that coding it
+will be like coding in some scripting language...
+
+
+
+char *get_param(char in_string[500], char swhat[500]);
+
+This function simply returns various data from the query string.
+ *Pass get_param NOTHING longer than 500 in length!
+
+ What do I pass where in_string is?
+ The query string.
+
+ What do I pass where swhat is?
+ One of two things...
+ Either 0 for the path of the 'page'
+ or you can pass it the param you wish to lookup.
+
+
+
+
+
+
+char *get_query(char *inquery);
+
+This function simply returns a query string from the raw server request.
+This is used once in main, I doubt you'll need it.
+
+
+
+
+
+void web_send(int sockin, char *in_data);
+
+Super easy way of sending data to a webpage!
+Simply put in the socket name and then the data.
+
+ Ex:
+ web_send(socket, "I like cheese!\n");
+
+
+
+
+char *html_header(char* title);
+Easy way to print the eAthena header for the server.
+
+ Ex:
+ web_send(sockethere, html_header("About"));
diff --git a/src/webserver/doc/README b/src/webserver/doc/README
new file mode 100644
index 000000000..0e94ff2ae
--- /dev/null
+++ b/src/webserver/doc/README
@@ -0,0 +1,11 @@
+This readme is intended for the programmers of eAthena.
+
+This webserver's apis are in API.txt.
+
+To make this simple, generate.c should handle most of the work this sever does
+in terms of what people see.
+
+When a request is made the server shoots it off to generate.c.
+
+You are welcome to create more functions used by generate.c to generate pages
+though, so don't feel limited by that one file.
diff --git a/src/webserver/generate.c b/src/webserver/generate.c
new file mode 100644
index 000000000..ad050db4c
--- /dev/null
+++ b/src/webserver/generate.c
@@ -0,0 +1,38 @@
+
+void generate_page(char password[25], int sock_in, char *query, char *ip)
+{
+ char *page = get_param(query, 0);
+ char *ppass = get_param(query, "password");
+
+
+ if ( (ppass == 0) || (strcmp(password, ppass) != 0) )
+ {
+ web_send(sock_in, html_header("Enter your password"));
+ web_send(sock_in, "<H1>NOT LOGGED IN!</H1><form action=\"/\" method=\"GET\">\n");
+ web_send(sock_in, "Enter your password:<br>\n<input type=\"text\" name=\"password\">\n");
+ web_send(sock_in, "<input type=\"submit\" value=\"Login\">\n");
+ }
+ else
+ {
+
+
+ //To make this simple, we will have a bunch of if statements
+ //that then shoot out data off into functions.
+
+
+ //The 'index'
+ if ( strcmp(page, "/") == 0 )
+ generate_notdone(sock_in, query, ip);
+
+
+ //About page:
+ if ( strcmp(page, "/about.html") == 0 )
+ generate_about(sock_in, query, ip);
+
+
+ //Test page:
+ if ( strcmp(page, "/testing/") == 0 )
+ generate_sample(sock_in, query, ip);
+
+ }
+}
diff --git a/src/webserver/htmlstyle.c b/src/webserver/htmlstyle.c
new file mode 100644
index 000000000..c3a4b927a
--- /dev/null
+++ b/src/webserver/htmlstyle.c
@@ -0,0 +1,51 @@
+char output[10000];
+
+char *html_header(char *title)
+{
+ memset(output, 0x0, 10000);
+ char *text = "<body text=\"#000000\" bgcolor=\"#939393\" link=\"#0033FF\">\n"
+ "<br><table width=\"92%\" cellspacing=\"1\" cellpadding=\"0\" border=\"0\"\n"
+ "align=\"center\" class=\"bordercolor\"><tbody><tr><td class=\"bordercolor\" width=\"100%\">\n"
+ "<table bgcolor=\"#ffffff\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\">\n"
+ "<tbody><tr><td><table border=\"0\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" bgcolor=\"#ffffff\">\n"
+ "<tbody><tr><img src=\"http://eathena.sourceforge.net/athena.jpg\" alt=\"Athena\">\n"
+ "<td bgcolor=\"#ffffff\"></td></tr></tbody></table></td></tr></tbody></table>\n"
+ "</td></tr><tr align=\"left\"><td class=\"bordercolor\"><table bgcolor=\"#c6c6c6\" width=\"100%\" cellspacing=\"0\"\n"
+ "cellpadding=\"0\" style=\"text-align: left; margin-right: auto; margin-left: 0px;\">\n";
+ "<tbody><tr><td width=\"100%\" align=\"center\"><table border=\"0\" width=\"100%\" cellpadding=\"3\"\n"
+ "cellspacing=\"0\" bgcolor=\"#c6c6c6\" align=\"center\"><tbody><tr>"
+ "<td valign=\"middle\" bgcolor=\"#c6c6c6\" align=\"center\"><a href=\"/cgi-bin/forum/YaBB.cgi\">"
+ "<span style=\"text-decoration: underline;\"><span style=\"font-weight: bold;\">\n"
+ "To the Forum</span></span></a><br></td></tr></tbody></table></td></tr></tbody>\n"
+ "</table></td></tr><tr><td class=\"bordercolor\" align=\"center\">\n"
+ "<table bgcolor=\"#ffffff\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" align=\"center\">\n"
+ "<tbody><tr><td width=\"100%\" align=\"center\"><table border=\"0\" width=\"100%\" cellpadding=\"5\"\n"
+ "cellspacing=\"0\" bgcolor=\"#ffffff\" align=\"center\"><tbody><tr>\n"
+ "<td valign=\"middle\" bgcolor=\"#ffffff\" align=\"center\"><font size=\"2\" color=\"#6e94b7\">\n"
+ "<b>Athena</b> &laquo; Portal &raquo;</font></td></tr></tbody></table></td></tr></tbody>"
+ "</table></td></tr></tbody></table>\n";
+
+ sprintf(output, "<title>%s</title>\n%s\n", title, text);
+
+ return output;
+}
+
+
+
+char *html_start_form(char *location, char *action)
+{
+ memset(output, 0x0, 10000);
+ sprintf(output, "<form action=\"%s\" method=\"%s\">", location, action);
+ return output;
+
+
+}
+
+
+char *html_end_forum(void)
+{
+ return "</form>";
+}
+
+
+
diff --git a/src/webserver/logs.c b/src/webserver/logs.c
new file mode 100644
index 000000000..405b4882b
--- /dev/null
+++ b/src/webserver/logs.c
@@ -0,0 +1,8 @@
+#include <time.h>
+
+void log_visit(char *query, char *ip)
+{
+ time_t timer;
+ timer=time(NULL);
+ printf("%s - \"%s\" - %s", ip, query, asctime(localtime(&timer)));
+}
diff --git a/src/webserver/main.c b/src/webserver/main.c
index 915d71b6d..59362558e 100644
--- a/src/webserver/main.c
+++ b/src/webserver/main.c
@@ -1,144 +1,142 @@
-/******************************************************************************
- # ______ __ __ #
- # /\ _ \/\ \__/\ \ #
- # __\ \ \L\ \ \ ,_\ \ \___ __ ___ __ #
- # /'__`\ \ __ \ \ \/\ \ _ `\ /'__`\/' _ `\ /'__`\ #
- # /\ __/\ \ \/\ \ \ \_\ \ \ \ \/\ __//\ \/\ \/\ \L\.\_ #
- # \ \____\\ \_\ \_\ \__\\ \_\ \_\ \____\ \_\ \_\ \__/.\_\ #
- # \/____/ \/_/\/_/\/__/ \/_/\/_/\/____/\/_/\/_/\/__/\/_/ #
- # eAthena Web Server (Second Edition) #
- # by MC Cameri #
- # ------------------------------------------------------- #
- # -Website/Forum- #
- # http://eathena.deltaanime.net/ #
- # -Download URL- #
- # http://eathena.systeminplace.net/ #
- # -IRC Channel- #
- # irc://irc.deltaanime.net/#athena #
- ******************************************************************************/
+/***************************************************************************
+ description
+ -------------------
+ author : (C) 2004 by Michael J. Flickinger
+ email : mjflick@cpan.org
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
#include <stdio.h>
#include <stdlib.h>
-#include <strings.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
-#include <unistd.h>
-#include <errno.h>
-#include "../common/showmsg.h"
-#include "webserver.h"
+#define BLOG 10
-char ws_password[17];
-char ws_header[128];
+char *header = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n";
+char recvin[500], password[25];
+int s_port;
-#define WEB_CONF "conf/webserver-athena.conf"
-#define MAX_CONNECTIONS 10
-#define HOME "home/"
-
-struct config config;
+void sigchld_handler(int s)
+{
+ while(wait(NULL) > 0);
+}
-int main(int argc, char *argv[])
+int main(int argc, char **argv)
{
- int server_fd, client_fd;
+ if (argc < 3)
+ {
+ printf("eAthena Web Server\n");
+ printf("usage: %s [password] [port]\n", argv[0]);
+ exit(0);
+ }
+
+ s_port = atoi(argv[2]);
+
+ if ((s_port < 1) || (s_port > 65534))
+ {
+ printf("Error: The port you choose is not valid port.\n");
+ exit(0);
+ }
+
+ if (strlen(argv[1]) > 25)
+ {
+ printf("Error: Your password is too long.\n");
+ printf("It must be shorter than 25 characters.\n");
+ exit(0);
+ }
+
+ memset(password, 0x0, 25);
+ memcpy(password, argv[1], strlen(argv[1]));
+
+ int sockfd, new_fd;
+ struct sockaddr_in my_addr;
+ struct sockaddr_in their_addr;
int sin_size;
- struct sockaddr_in server_addr;
- struct sockaddr_in client_addr;
+
struct sigaction sa;
- char recvin[1024];
- char path[1024];
- char line[1024];
- int optval = 1;
- if (ws_config_read(WEB_CONF)) exit(0);
- if (config.show_title)
- ws_display_title();
- else
- printf("eAthena Web Server (Second Edition)\n");
- if (strcmpEx(ws_password,"webpass")==0)
- ShowWarning("You are using the default password (webpass), we highly "
- "recommend\n that you change it.\n");
- else if (strstr(ws_password,"webpass"))
- ShowWarning("Your password should not contain \"webpass\" in it, it is"
- " highly\n recommended that you change it.\n");
- printf("Web Server Password: %s\n",ws_password);
- printf("Web Server Port: %d\n",config.port);
-
- if ((server_fd = socket(AF_INET, SOCK_STREAM,0)) == -1) {
- ShowError("In main() -> Could not open socket.\n");
- return 1;
+
+ int yes=1;
+
+ if ((sockfd = socket(AF_INET, SOCK_STREAM,0)) == -1)
+ {
+ perror("Darn, this is broken.");
+ exit(0);
}
- if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int)) == -1) {
- ShowError("In main() -> Could not set socket options.\n");
- return 1;
+
+ if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
+ {
+ perror("Error... :-(");
}
- server_addr.sin_family = AF_INET;
- server_addr.sin_port = htons(config.port);
- server_addr.sin_addr.s_addr = INADDR_ANY;
- memset(&(server_addr.sin_zero), '\0', 8);
-
- if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0) {
- snprintf(tmp_output,sizeof(tmp_output),"In main() -> Could not bind to port number: %d\n",config.port);
- ShowError(tmp_output);
- return 1;
+
+ //Now we know we have a working socket. :-)
+
+ my_addr.sin_family = AF_INET;
+ my_addr.sin_port = htons(s_port);
+ my_addr.sin_addr.s_addr = INADDR_ANY;
+ memset(&(my_addr.sin_zero), '\0', 8);
+
+ if ( bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
+ {
+ perror("can not bind to this port");
+ exit(0);
}
- if (listen(server_fd, MAX_CONNECTIONS) < 0) {
- snprintf(tmp_output,sizeof(tmp_output),"In main() -> Could not listen on port number: %d\n",config.port);
- ShowError(tmp_output);
- return 1;
+ if ( listen(sockfd, BLOG) == -1)
+ {
+ perror("can not listen on port");
+ exit(0);
}
- sa.sa_handler = ws_sigchld_handler;
+ sa.sa_handler = sigchld_handler;
+
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
- if (sigaction(SIGCHLD, &sa, NULL) < 0) {
- ShowError("In main() -> Invalid sigaction.\n");
- return 1;
+ if (sigaction(SIGCHLD, &sa, NULL) == -1)
+ {
+ perror("sigaction sucks");
+ exit(0);
}
- ShowInfo("eAthena Web Server is now listening for incoming connections.\n");
+
+ printf("The eAthena webserver is up and listening on port %i.\n", s_port);
while(1)
{
sin_size = sizeof(struct sockaddr_in);
- client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &sin_size);
+ new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
if (!fork())
{
- close(server_fd);
+ close(sockfd);
memset(recvin, 0x0, 500);
- recv(client_fd, recvin, 500, 0);
- char *html_output;
- int count = 0;
- if (sscanf(recvin,"GET %[a-zA-Z_-.+\%#@~] %*[^\n]",path)==1) {
- FILE *fp;
- strcpy(tmp_output,HOME);
- strcat(tmp_output,path);
- fp = fopen(tmp_output,"r+");
- if (fp==NULL) {
- send(client_fd,"File not found",strlen("File not found"), 0);
- close(client_fd);
- }
- memset(tmp_output,0x0,strlen(tmp_output));
- html_output = (char*)malloc(sizeof(char)*2);
- while (fgets(line,1023,fp)) {
- html_output = (char*)realloc(sizeof(html_output)+(sizeof(char)*count));
- strcat(html_output,line);
- printf(line);
- }
- send(client_fd,tmp_output,sizeof(tmp_output),0);
- fclose(fp);
- }
- // send(client_fd, ws_header, strlen(ws_header), 0);
- // generate_page(password, client_fd, get_query(recvin), inet_ntoa(client_addr.sin_addr));
- // log_visit(get_query(recvin), inet_ntoa(client_addr.sin_addr));
- close(client_fd);
+ recv(new_fd, recvin, 500, 0);
+ send(new_fd, header, strlen(header), 0);
+ generate_page(password, new_fd, get_query(recvin), inet_ntoa(their_addr.sin_addr));
+ log_visit(get_query(recvin), inet_ntoa(their_addr.sin_addr));
+
+ close(new_fd);
exit(0);
}
- close(client_fd);
+ close(new_fd);
}
+
return 0;
}
diff --git a/src/webserver/pages/about.c b/src/webserver/pages/about.c
new file mode 100644
index 000000000..2b0002ad8
--- /dev/null
+++ b/src/webserver/pages/about.c
@@ -0,0 +1,6 @@
+void generate_about(int sock_in, char *query, char *ip)
+{
+//printf("%s", html_header("About"));
+ web_send(sock_in, html_header("About"));
+ web_send(sock_in, "<center>eAthena Web Server!</center>\n");
+}
diff --git a/src/webserver/pages/notdone.c b/src/webserver/pages/notdone.c
new file mode 100644
index 000000000..a6492e361
--- /dev/null
+++ b/src/webserver/pages/notdone.c
@@ -0,0 +1,5 @@
+void generate_notdone(int sock_in, char *query, char *ip)
+{
+ web_send(sock_in, "<title>Not here!</title>\n");
+ web_send(sock_in, "<h2><center>This page/feature is not done yet.</center>\n</h2>");
+}
diff --git a/src/webserver/pages/sample.c b/src/webserver/pages/sample.c
new file mode 100644
index 000000000..be900a1bf
--- /dev/null
+++ b/src/webserver/pages/sample.c
@@ -0,0 +1,24 @@
+
+
+void generate_sample(int sock_in, char *query, char *ip)
+{
+
+ char *name = get_param(query, "name");
+
+ web_send(sock_in, "<title>SAMPLE</title>\n");
+
+
+ //If a name was not entered...
+ if ( name == '\0' )
+ {
+ web_send(sock_in, "<form action=\"/testing/\" method=\"GET\">\n");
+ web_send(sock_in, "<input type=\"text\" name=\"name\">\n");
+ web_send(sock_in, "<input type=\"submit\">\n");
+ }
+ else
+ {
+ web_send(sock_in, "Your name is: ");
+ web_send(sock_in, get_param(query, "name"));
+ }
+printf("OK!\n");
+}
diff --git a/src/webserver/parse.c b/src/webserver/parse.c
new file mode 100644
index 000000000..8e54a81de
--- /dev/null
+++ b/src/webserver/parse.c
@@ -0,0 +1,135 @@
+#include <stdlib.h>
+
+char filtered_query[2000];
+char rdata[500];
+char param_n[500];
+char param_d[500];
+
+
+char *get_query(char *inquery)
+{
+ memset(filtered_query, 0x0, 2000);
+ sscanf(inquery, "GET %s %[$]", filtered_query);
+ return(filtered_query);
+}
+
+void web_send(int sockin, char *in_data)
+{
+ send(sockin, in_data, strlen(in_data), 0);
+}
+
+
+//THIS IS BAD CODE BE CAREFULL WITH IT!
+//Watch out for buffer overflow...
+//When using please make sure to check the string size.
+
+//Also note:
+//I take no pride in this code, it is a really bad way of doing this...
+char *get_param(char in_string[500], char swhat[500])
+{
+ int i = 0;
+ int marker, iswitch, pint, dint;
+ char flux[500];
+ memset(flux, 0x0, 500);
+
+ //Get the path of out "page"
+ if (swhat == 0)
+ {
+ //while i is not equal to array size
+ while (i != 500)
+ {
+ //if there is a question mark, halt!
+ if (in_string[i] == '?')
+ {
+ i = 499;
+ }
+ else
+ rdata[i] = in_string[i];
+
+ i++;
+ }
+ return rdata;
+ }
+ else //so, we want a param...
+ {
+ //calculate where param begins
+ while (i != 500)
+ {
+ if (in_string[i] == '?')
+ {
+ marker = i + 1;
+ i = 499;
+ }
+ i++;
+ }
+
+ i = 0;
+
+ //keep morons from trying to crash this
+ if ((marker > 500)||(marker < 1))
+ marker = 500;
+
+ while(marker != 500)
+ {
+ if ((in_string[marker] != '&') && (in_string[marker] != '\0'))
+ {
+ flux[i] = in_string[marker];
+ i++;
+ }
+ else
+ {
+
+ //we have a param, now we must dig through it
+
+ //clear temp vars
+ memset(param_n, 0x0, 500);
+ memset(param_d, 0x0, 500);
+ iswitch = 0;
+ pint = 0;
+ dint = 0;
+ i = 0;
+
+ //split result into param_n and param_d
+ while(i != 500)
+ {
+ if ( (flux[i] != '=') && (flux[i] != '\0') )
+ {
+ if (iswitch == 0)
+ {
+ param_n[pint] = flux[i];
+ pint++;
+ }
+ else
+ {
+ param_d[dint] = flux[i];
+ dint++;
+ }
+ }
+ else
+ {
+ iswitch = 1;
+ }
+ if (flux[i] == '\0')
+ i = 499;
+
+ i++;
+ }
+
+ if ( strcmp(param_n, swhat) == 0 )
+ {
+ return param_d;
+ }
+
+ i = 0;
+ }
+
+ if (in_string[marker] == '\0')
+ {
+ marker = 499;
+ }
+ marker++;
+ }
+ return 0;
+ }
+}
+
diff --git a/src/webserver/webserver.c b/src/webserver/webserver.c
deleted file mode 100644
index 0169cd028..000000000
--- a/src/webserver/webserver.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/******************************************************************************
- # ______ __ __ #
- # /\ _ \/\ \__/\ \ #
- # __\ \ \L\ \ \ ,_\ \ \___ __ ___ __ #
- # /'__`\ \ __ \ \ \/\ \ _ `\ /'__`\/' _ `\ /'__`\ #
- # /\ __/\ \ \/\ \ \ \_\ \ \ \ \/\ __//\ \/\ \/\ \L\.\_ #
- # \ \____\\ \_\ \_\ \__\\ \_\ \_\ \____\ \_\ \_\ \__/.\_\ #
- # \/____/ \/_/\/_/\/__/ \/_/\/_/\/____/\/_/\/_/\/__/\/_/ #
- # eAthena Web Server (Second Edition) #
- # by MC Cameri #
- # ------------------------------------------------------- #
- # -Website/Forum- #
- # http://eathena.deltaanime.net/ #
- # -Download URL- #
- # http://eathena.systeminplace.net/ #
- # -IRC Channel- #
- # irc://irc.deltaanime.net/#athena #
- ******************************************************************************/
-
-#include <stdio.h>
-#include <strings.h>
-#include "../common/showmsg.h"
-#include "webserver.h"
-
-char ws_password[17] = "pass";
-char ws_header[128] = {'\0'};
-
-/* Displays the eAthena Logo */
-void ws_display_title(void)
-{
- printf("\033[2J");
- printf("\033[37;44m (=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)\033[K\033[0m\n");
- printf("\033[0;44m (\033[1;33m (c)2004 eAthena Development Team presents \033[0;44m)\033[K\033[0m\n");
- printf("\033[0;44m (\033[1m ______ __ __ \033[0;44m)\033[K\033[0m\n");
- printf("\033[0;44m (\033[1m /\\ _ \\/\\ \\__/\\ \\ \033[0;44m)\033[K\033[0m\n");
- printf("\033[0;44m (\033[1m __\\ \\ \\_\\ \\ \\ ,_\\ \\ \\___ __ ___ __ \033[0;44m)\033[K\033[0m\n");
- printf("\033[0;44m (\033[1m /'__`\\ \\ __ \\ \\ \\/\\ \\ _ `\\ /'__`\\/' _ `\\ /'__`\\ \033[0;44m)\033[K\033[0m\n");
- printf("\033[0;44m (\033[1m /\\ __/\\ \\ \\/\\ \\ \\ \\_\\ \\ \\ \\ \\/\\ __//\\ \\/\\ \\/\\ \\_\\.\\_ \033[0;44m)\033[K\033[0m\n");
- printf("\033[0;44m (\033[1m \\ \\____\\\\ \\_\\ \\_\\ \\__\\\\ \\_\\ \\_\\ \\____\\ \\_\\ \\_\\ \\__/.\\_\\ \033[0;44m)\033[K\033[0m\n");
- printf("\033[0;44m (\033[1m \\/____/ \\/_/\\/_/\\/__/ \\/_/\\/_/\\/____/\\/_/\\/_/\\/__/\\/_/ \033[0;44m)\033[K\033[0m\n");
- printf("\033[0;44m (\033[1m _ _ _ _ _ _ _ _ _ _ _ _ _ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
- printf("\033[0;44m (\033[1m / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
- printf("\033[0;44m (\033[1m ( e | n | g | l | i | s | h ) ( A | t | h | e | n | a ) \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
- printf("\033[0;44m (\033[1m \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
- printf("\033[0;44m (\033[1m \033[0;44m)\033[K\033[0m\n"); // yellow writing (33)
- printf("\033[0;44m (\033[1;33m Advanced Fusion Maps (c) 2003-2004 The Fusion Project \033[0;44m)\033[K\033[0m\n"); // yellow writing (33)
- printf("\033[37;44m (=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)\033[K\033[0m\n\n"); // reset color
-}
-/* Returns a boolean value given character string */
-int ws_config_switch(const char *str) {
- if (strcmpEx(str, "on") == 0 || strcmpEx(str, "yes") == 0 ||
- strcmpEx(str, "oui") == 0 || strcmpEx(str, "ja") == 0 ||
- strcmpEx(str, "si") == 0 || strcmpEx(str,"true") == 0)
- return 1;
- if (strcmpEx(str, "off") == 0 || strcmpEx(str, "no") == 0 ||
- strcmpEx(str, "non") == 0 || strcmpEx(str, "nein") == 0 ||
- strcmpEx(str, "false") == 0)
- return 0;
- return atoi(str);
-}
-
-/* Reads the eAthena Web Server's configuration file */
-int ws_config_read(const char *cfgName)
-{
- int i;
- char line[1024],w1[1024],w2[1024],temp[1024];
- FILE *fp;
-
- /* Default values */
- config.show_title=0;
- config.port=80;
-
-
- fp=fopen(cfgName,"r");
- if(fp==NULL){
- snprintf(temp,sizeof(temp),"Could not open \033[1;29m%s\033[0;0m, file not found.\n",cfgName);
- ShowMessage(temp,MSG_ERROR);
- return 1;
- }
- while(fgets(line,1020,fp)){
- const struct {
- char str[128];
- int *val;
- } data[] ={
- //List of variables
- { "show_title", &config.show_title },
- { "port", &config.port },
- };
-
- if((line[0] == '/' && line[1] == '/') || (line[0]=='#') ||
- (sscanf(line,"%1023[^:]:%1023[^\n]",w1,w2) !=2))
- continue;
- for(i=0;i<sizeof(data)/(sizeof(data[0]));i++) {
- if(strcmpEx(w1,data[i].str)==0){
- *data[i].val=ws_config_switch(w2);
- break;
- }
- }
- if(strcmpEx(w1,"import")==0) {
- ws_config_read(w2);
- continue;
- }
- if(strcmpEx(w1,"password")==0) {
- if (strlen(w2)>16) {
- ShowError("The Web Server password is too long, maximum passwor"
- "d length is 16 characters.\n");
- return 1;
- }
- strcpy(ws_password,w2);
- continue;
- }
- if(strcmpEx(w1,"header")==0) {
- if (strlen(w2)>127) {
- ShowError("The Web Server header is too long, maximum header"
- "d length is 127 characters.\n");
- return 1;
- }
- strcpy(ws_header,w2);
- continue;
- }
- }
- fclose(fp);
-
- //Correct values
- if(config.show_title < 0)
- config.show_title = 0;
- if(config.port < 1 || config.port > 65534)
- config.port=80;
-
- return 0;
-}
-
-void ws_sigchld_handler(int s)
-{
- while(wait(NULL) > 0);
-}
diff --git a/src/webserver/webserver.h b/src/webserver/webserver.h
deleted file mode 100644
index 84ef02b62..000000000
--- a/src/webserver/webserver.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef WEBSERV_H_
-#define WEBSERV_H_
-
-#define strcmpEx(x,y) (strcasecmp(x,y))
-
-extern void ws_display_title(void);
-
-extern int ws_config_read(const char *cfgName);
-
-extern struct config {
- int show_title;
- int port;
-} config;
-
-extern char ws_password[17]; //16 chars + \0
-
-extern char ws_header[128]; //!?
-
-extern void ws_sigchld_handler(int s);
-
-#endif
diff --git a/src/zlib/FAQ b/src/zlib/FAQ
new file mode 100644
index 000000000..4f61f1094
--- /dev/null
+++ b/src/zlib/FAQ
@@ -0,0 +1,337 @@
+
+ Frequently Asked Questions about zlib
+
+
+If your question is not there, please check the zlib home page
+http://www.zlib.org which may have more recent information.
+The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
+
+
+ 1. Is zlib Y2K-compliant?
+
+ Yes. zlib doesn't handle dates.
+
+ 2. Where can I get a Windows DLL version?
+
+ The zlib sources can be compiled without change to produce a DLL.
+ See the file win32/DLL_FAQ.txt in the zlib distribution.
+ Pointers to the precompiled DLL are found in the zlib web site at
+ http://www.zlib.org.
+
+ 3. Where can I get a Visual Basic interface to zlib?
+
+ See
+ * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm
+ * contrib/visual-basic.txt in the zlib distribution
+ * win32/DLL_FAQ.txt in the zlib distribution
+
+ 4. compress() returns Z_BUF_ERROR.
+
+ Make sure that before the call of compress, the length of the compressed
+ buffer is equal to the total size of the compressed buffer and not
+ zero. For Visual Basic, check that this parameter is passed by reference
+ ("as any"), not by value ("as long").
+
+ 5. deflate() or inflate() returns Z_BUF_ERROR.
+
+ Before making the call, make sure that avail_in and avail_out are not
+ zero. When setting the parameter flush equal to Z_FINISH, also make sure
+ that avail_out is big enough to allow processing all pending input.
+ Note that a Z_BUF_ERROR is not fatal--another call to deflate() or
+ inflate() can be made with more input or output space. A Z_BUF_ERROR
+ may in fact be unavoidable depending on how the functions are used, since
+ it is not possible to tell whether or not there is more output pending
+ when strm.avail_out returns with zero.
+
+ 6. Where's the zlib documentation (man pages, etc.)?
+
+ It's in zlib.h for the moment, and Francis S. Lin has converted it to a
+ web page zlib.html. Volunteers to transform this to Unix-style man pages,
+ please contact us (zlib@gzip.org). Examples of zlib usage are in the files
+ example.c and minigzip.c.
+
+ 7. Why don't you use GNU autoconf or libtool or ...?
+
+ Because we would like to keep zlib as a very small and simple
+ package. zlib is rather portable and doesn't need much configuration.
+
+ 8. I found a bug in zlib.
+
+ Most of the time, such problems are due to an incorrect usage of
+ zlib. Please try to reproduce the problem with a small program and send
+ the corresponding source to us at zlib@gzip.org . Do not send
+ multi-megabyte data files without prior agreement.
+
+ 9. Why do I get "undefined reference to gzputc"?
+
+ If "make test" produces something like
+
+ example.o(.text+0x154): undefined reference to `gzputc'
+
+ check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
+ /usr/X11R6/lib. Remove any old versions, then do "make install".
+
+10. I need a Delphi interface to zlib.
+
+ See the contrib/delphi directory in the zlib distribution.
+
+11. Can zlib handle .zip archives?
+
+ Not by itself, no. See the directory contrib/minizip in the zlib
+ distribution.
+
+12. Can zlib handle .Z files?
+
+ No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt
+ the code of uncompress on your own.
+
+13. How can I make a Unix shared library?
+
+ make clean
+ ./configure -s
+ make
+
+14. How do I install a shared zlib library on Unix?
+
+ After the above, then:
+
+ make install
+
+ However, many flavors of Unix come with a shared zlib already installed.
+ Before going to the trouble of compiling a shared version of zlib and
+ trying to install it, you may want to check if it's already there! If you
+ can #include <zlib.h>, it's there. The -lz option will probably link to it.
+
+15. I have a question about OttoPDF.
+
+ We are not the authors of OttoPDF. The real author is on the OttoPDF web
+ site: Joel Hainley, jhainley@myndkryme.com.
+
+16. Can zlib decode Flate data in an Adobe PDF file?
+
+ Yes. See http://www.fastio.com/ (ClibPDF), or http://www.pdflib.com/ .
+ To modify PDF forms, see http://sourceforge.net/projects/acroformtool/ .
+
+17. Why am I getting this "register_frame_info not found" error on Solaris?
+
+ After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib
+ generates an error such as:
+
+ ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so:
+ symbol __register_frame_info: referenced symbol not found
+
+ The symbol __register_frame_info is not part of zlib, it is generated by
+ the C compiler (cc or gcc). You must recompile applications using zlib
+ which have this problem. This problem is specific to Solaris. See
+ http://www.sunfreeware.com for Solaris versions of zlib and applications
+ using zlib.
+
+18. Why does gzip give an error on a file I make with compress/deflate?
+
+ The compress and deflate functions produce data in the zlib format, which
+ is different and incompatible with the gzip format. The gz* functions in
+ zlib on the other hand use the gzip format. Both the zlib and gzip
+ formats use the same compressed data format internally, but have different
+ headers and trailers around the compressed data.
+
+19. Ok, so why are there two different formats?
+
+ The gzip format was designed to retain the directory information about
+ a single file, such as the name and last modification date. The zlib
+ format on the other hand was designed for in-memory and communication
+ channel applications, and has a much more compact header and trailer and
+ uses a faster integrity check than gzip.
+
+20. Well that's nice, but how do I make a gzip file in memory?
+
+ You can request that deflate write the gzip format instead of the zlib
+ format using deflateInit2(). You can also request that inflate decode
+ the gzip format using inflateInit2(). Read zlib.h for more details.
+
+ Note that you cannot specify special gzip header contents (e.g. a file
+ name or modification date), nor will inflate tell you what was in the
+ gzip header. If you need to customize the header or see what's in it,
+ you can use the raw deflate and inflate operations and the crc32()
+ function and roll your own gzip encoding and decoding. Read the gzip
+ RFC 1952 for details of the header and trailer format.
+
+21. Is zlib thread-safe?
+
+ Yes. However any library routines that zlib uses and any application-
+ provided memory allocation routines must also be thread-safe. zlib's gz*
+ functions use stdio library routines, and most of zlib's functions use the
+ library memory allocation routines by default. zlib's Init functions allow
+ for the application to provide custom memory allocation routines.
+
+ Of course, you should only operate on any given zlib or gzip stream from a
+ single thread at a time.
+
+22. Can I use zlib in my commercial application?
+
+ Yes. Please read the license in zlib.h.
+
+23. Is zlib under the GNU license?
+
+ No. Please read the license in zlib.h.
+
+24. The license says that altered source versions must be "plainly marked". So
+ what exactly do I need to do to meet that requirement?
+
+ You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In
+ particular, the final version number needs to be changed to "f", and an
+ identification string should be appended to ZLIB_VERSION. Version numbers
+ x.x.x.f are reserved for modifications to zlib by others than the zlib
+ maintainers. For example, if the version of the base zlib you are altering
+ is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
+ ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also
+ update the version strings in deflate.c and inftrees.c.
+
+ For altered source distributions, you should also note the origin and
+ nature of the changes in zlib.h, as well as in ChangeLog and README, along
+ with the dates of the alterations. The origin should include at least your
+ name (or your company's name), and an email address to contact for help or
+ issues with the library.
+
+ Note that distributing a compiled zlib library along with zlib.h and
+ zconf.h is also a source distribution, and so you should change
+ ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes
+ in zlib.h as you would for a full source distribution.
+
+25. Will zlib work on a big-endian or little-endian architecture, and can I
+ exchange compressed data between them?
+
+ Yes and yes.
+
+26. Will zlib work on a 64-bit machine?
+
+ It should. It has been tested on 64-bit machines, and has no dependence
+ on any data types being limited to 32-bits in length. If you have any
+ difficulties, please provide a complete problem report to zlib@gzip.org
+
+27. Will zlib decompress data from the PKWare Data Compression Library?
+
+ No. The PKWare DCL uses a completely different compressed data format
+ than does PKZIP and zlib. However, you can look in zlib's contrib/blast
+ directory for a possible solution to your problem.
+
+28. Can I access data randomly in a compressed stream?
+
+ No, not without some preparation. If when compressing you periodically
+ use Z_FULL_FLUSH, carefully write all the pending data at those points,
+ and keep an index of those locations, then you can start decompression
+ at those points. You have to be careful to not use Z_FULL_FLUSH too
+ often, since it can significantly degrade compression.
+
+29. Does zlib work on MVS, OS/390, CICS, etc.?
+
+ We don't know for sure. We have heard occasional reports of success on
+ these systems. If you do use it on one of these, please provide us with
+ a report, instructions, and patches that we can reference when we get
+ these questions. Thanks.
+
+30. Is there some simpler, easier to read version of inflate I can look at
+ to understand the deflate format?
+
+ First off, you should read RFC 1951. Second, yes. Look in zlib's
+ contrib/puff directory.
+
+31. Does zlib infringe on any patents?
+
+ As far as we know, no. In fact, that was originally the whole point behind
+ zlib. Look here for some more information:
+
+ http://www.gzip.org/#faq11
+
+32. Can zlib work with greater than 4 GB of data?
+
+ Yes. inflate() and deflate() will process any amount of data correctly.
+ Each call of inflate() or deflate() is limited to input and output chunks
+ of the maximum value that can be stored in the compiler's "unsigned int"
+ type, but there is no limit to the number of chunks. Note however that the
+ strm.total_in and strm_total_out counters may be limited to 4 GB. These
+ counters are provided as a convenience and are not used internally by
+ inflate() or deflate(). The application can easily set up its own counters
+ updated after each call of inflate() or deflate() to count beyond 4 GB.
+ compress() and uncompress() may be limited to 4 GB, since they operate in a
+ single call. gzseek() and gztell() may be limited to 4 GB depending on how
+ zlib is compiled. See the zlibCompileFlags() function in zlib.h.
+
+ The word "may" appears several times above since there is a 4 GB limit
+ only if the compiler's "long" type is 32 bits. If the compiler's "long"
+ type is 64 bits, then the limit is 16 exabytes.
+
+33. Does zlib have any security vulnerabilities?
+
+ The only one that we are aware of is potentially in gzprintf(). If zlib
+ is compiled to use sprintf() or vsprintf(), then there is no protection
+ against a buffer overflow of a 4K string space, other than the caller of
+ gzprintf() assuring that the output will not exceed 4K. On the other
+ hand, if zlib is compiled to use snprintf() or vsnprintf(), which should
+ normally be the case, then there is no vulnerability. The ./configure
+ script will display warnings if an insecure variation of sprintf() will
+ be used by gzprintf(). Also the zlibCompileFlags() function will return
+ information on what variant of sprintf() is used by gzprintf().
+
+ If you don't have snprintf() or vsnprintf() and would like one, you can
+ find a portable implementation here:
+
+ http://www.ijs.si/software/snprintf/
+
+ Note that you should be using the most recent version of zlib. Versions
+ 1.1.3 and before were subject to a double-free vulnerability.
+
+34. Is there a Java version of zlib?
+
+ Probably what you want is to use zlib in Java. zlib is already included
+ as part of the Java SDK in the java.util.zip package. If you really want
+ a version of zlib written in the Java language, look on the zlib home
+ page for links: http://www.zlib.org/
+
+35. I get this or that compiler or source-code scanner warning when I crank it
+ up to maximally-pedantic. Can't you guys write proper code?
+
+ Many years ago, we gave up attempting to avoid warnings on every compiler
+ in the universe. It just got to be a waste of time, and some compilers
+ were downright silly. So now, we simply make sure that the code always
+ works.
+
+36. Will zlib read the (insert any ancient or arcane format here) compressed
+ data format?
+
+ Probably not. Look in the comp.compression FAQ for pointers to various
+ formats and associated software.
+
+37. How can I encrypt/decrypt zip files with zlib?
+
+ zlib doesn't support encryption. The original PKZIP encryption is very weak
+ and can be broken with freely available programs. To get strong encryption,
+ use GnuPG, http://www.gnupg.org/ , which already includes zlib compression.
+ For PKZIP compatible "encryption", look at http://www.info-zip.org/
+
+38. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
+
+ "gzip" is the gzip format, and "deflate" is the zlib format. They should
+ probably have called the second one "zlib" instead to avoid confusion
+ with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616
+ correctly points to the zlib specification in RFC 1950 for the "deflate"
+ transfer encoding, there have been reports of servers and browsers that
+ incorrectly produce or expect raw deflate data per the deflate
+ specficiation in RFC 1951, most notably Microsoft. So even though the
+ "deflate" transfer encoding using the zlib format would be the more
+ efficient approach (and in fact exactly what the zlib format was designed
+ for), using the "gzip" transfer encoding is probably more reliable due to
+ an unfortunate choice of name on the part of the HTTP 1.1 authors.
+
+ Bottom line: use the gzip format for HTTP 1.1 encoding.
+
+39. Does zlib support the new "Deflate64" format introduced by PKWare?
+
+ No. PKWare has apparently decided to keep that format proprietary, since
+ they have not documented it as they have previous compression formats.
+ In any case, the compression improvements are so modest compared to other
+ more modern approaches, that it's not worth the effort to implement.
+
+40. Can you please sign these lengthy legal documents and fax them back to us
+ so that we can use your software in our product?
+
+ No. Go away. Shoo.
diff --git a/src/zlib/README b/src/zlib/README
new file mode 100644
index 000000000..df95ae13f
--- /dev/null
+++ b/src/zlib/README
@@ -0,0 +1,126 @@
+ZLIB DATA COMPRESSION LIBRARY
+
+zlib 1.2.2 is a general purpose data compression library. All the code is
+thread safe. The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
+and rfc1952.txt (gzip format). These documents are also available in other
+formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
+of the library is given in the file example.c which also tests that the library
+is working correctly. Another example is given in the file minigzip.c. The
+compression library itself is composed of all source files except example.c and
+minigzip.c.
+
+To compile all files and run the test program, follow the instructions given at
+the top of Makefile. In short "make test; make install" should work for most
+machines. For Unix: "./configure; make test; make install" For MSDOS, use one
+of the special makefiles such as Makefile.msc. For VMS, use Make_vms.com or
+descrip.mms.
+
+Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
+<info@winimage.com> for the Windows DLL version. The zlib home page is
+http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem,
+please check this site to verify that you have the latest version of zlib;
+otherwise get the latest version and check whether the problem still exists or
+not.
+
+PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking
+for help.
+
+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
+issue of Dr. Dobb's Journal; a copy of the article is available in
+http://dogma.net/markn/articles/zlibtool/zlibtool.htm
+
+The changes made in version 1.2.2 are documented in the file ChangeLog.
+
+Unsupported third party contributions are provided in directory "contrib".
+
+A Java implementation of zlib is available in the Java Development Kit
+http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html
+See the zlib home page http://www.zlib.org for details.
+
+A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is in the
+CPAN (Comprehensive Perl Archive Network) sites
+http://www.cpan.org/modules/by-module/Compress/
+
+A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
+available in Python 1.5 and later versions, see
+http://www.python.org/doc/lib/module-zlib.html
+
+A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> is
+availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html
+
+An experimental package to read and write files in .zip format, written on top
+of zlib by Gilles Vollant <info@winimage.com>, is available in the
+contrib/minizip directory of zlib.
+
+
+Notes for some targets:
+
+- For Windows DLL versions, please see win32/DLL_FAQ.txt
+
+- For 64-bit Irix, deflate.c must be compiled without any optimization. With
+ -O, one libpng test fails. The test works in 32 bit mode (with the -n32
+ compiler flag). The compiler bug has been reported to SGI.
+
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
+ when compiled with cc.
+
+- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
+ necessary to get gzprintf working correctly. This is done by configure.
+
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
+ other compilers. Use "make test" to check your compiler.
+
+- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
+
+- For PalmOs, see http://palmzlib.sourceforge.net/
+
+- When building a shared, i.e. dynamic library on Mac OS X, the library must be
+ installed before testing (do "make install" before "make test"), since the
+ library location is specified in the library.
+
+
+Acknowledgments:
+
+ The deflate format used by zlib was defined by Phil Katz. The deflate
+ and zlib specifications were written by L. Peter Deutsch. Thanks to all the
+ people who reported problems and suggested various improvements in zlib;
+ they are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not*
+receiving lengthy legal documents to sign. The sources are provided
+for free but without warranty of any kind. The library has been
+entirely written by Jean-loup Gailly and Mark Adler; it does not
+include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include
+in the file ChangeLog history information documenting your changes. Please
+read the FAQ for more information on the distribution of modified source
+versions.
diff --git a/src/zlib/adler32.c b/src/zlib/adler32.c
new file mode 100644
index 000000000..624a1696e
--- /dev/null
+++ b/src/zlib/adler32.c
@@ -0,0 +1,74 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+#define BASE 65521UL /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf) DO8(buf,0); DO8(buf,8);
+
+#ifdef NO_DIVIDE
+# define MOD(a) \
+ do { \
+ if (a >= (BASE << 16)) a -= (BASE << 16); \
+ if (a >= (BASE << 15)) a -= (BASE << 15); \
+ if (a >= (BASE << 14)) a -= (BASE << 14); \
+ if (a >= (BASE << 13)) a -= (BASE << 13); \
+ if (a >= (BASE << 12)) a -= (BASE << 12); \
+ if (a >= (BASE << 11)) a -= (BASE << 11); \
+ if (a >= (BASE << 10)) a -= (BASE << 10); \
+ if (a >= (BASE << 9)) a -= (BASE << 9); \
+ if (a >= (BASE << 8)) a -= (BASE << 8); \
+ if (a >= (BASE << 7)) a -= (BASE << 7); \
+ if (a >= (BASE << 6)) a -= (BASE << 6); \
+ if (a >= (BASE << 5)) a -= (BASE << 5); \
+ if (a >= (BASE << 4)) a -= (BASE << 4); \
+ if (a >= (BASE << 3)) a -= (BASE << 3); \
+ if (a >= (BASE << 2)) a -= (BASE << 2); \
+ if (a >= (BASE << 1)) a -= (BASE << 1); \
+ if (a >= BASE) a -= BASE; \
+ } while (0)
+#else
+# define MOD(a) a %= BASE
+#endif
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+ uLong adler;
+ const Bytef *buf;
+ uInt len;
+{
+ unsigned long s1 = adler & 0xffff;
+ unsigned long s2 = (adler >> 16) & 0xffff;
+ int k;
+
+ if (buf == Z_NULL) return 1L;
+
+ while (len > 0) {
+ k = len < NMAX ? (int)len : NMAX;
+ len -= k;
+ while (k >= 16) {
+ DO16(buf);
+ buf += 16;
+ k -= 16;
+ }
+ if (k != 0) do {
+ s1 += *buf++;
+ s2 += s1;
+ } while (--k);
+ MOD(s1);
+ MOD(s2);
+ }
+ return (s2 << 16) | s1;
+}
diff --git a/src/zlib/compress.c b/src/zlib/compress.c
new file mode 100644
index 000000000..24ef02919
--- /dev/null
+++ b/src/zlib/compress.c
@@ -0,0 +1,79 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least 0.1% larger than sourceLen plus
+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+ int level;
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef*)source;
+ stream.avail_in = (uInt)sourceLen;
+#ifdef MAXSEG_64K
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+#endif
+ stream.next_out = dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+ stream.opaque = (voidpf)0;
+
+ err = deflateInit(&stream, level);
+ if (err != Z_OK) return err;
+
+ err = deflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ deflateEnd(&stream);
+ return err == Z_OK ? Z_BUF_ERROR : err;
+ }
+ *destLen = stream.total_out;
+
+ err = deflateEnd(&stream);
+ return err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
+
+/* ===========================================================================
+ If the default memLevel or windowBits for deflateInit() is changed, then
+ this function needs to be updated.
+ */
+uLong ZEXPORT compressBound (sourceLen)
+ uLong sourceLen;
+{
+ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
+}
diff --git a/src/zlib/crc32.c b/src/zlib/crc32.c
new file mode 100644
index 000000000..b39c7e125
--- /dev/null
+++ b/src/zlib/crc32.c
@@ -0,0 +1,333 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors. This results about a factor
+ * of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+/* @(#) $Id$ */
+
+/*
+ Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+ protection on the static variables used to control the first-use generation
+ of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+ first call get_crc_table() to initialize the tables before allowing more than
+ one thread to use crc32().
+ */
+
+#ifdef MAKECRCH
+# include <stdio.h>
+# ifndef DYNAMIC_CRC_TABLE
+# define DYNAMIC_CRC_TABLE
+# endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h" /* for STDC and FAR definitions */
+
+#define local static
+
+/* Find a four-byte integer type for crc32_little() and crc32_big(). */
+#ifndef NOBYFOUR
+# ifdef STDC /* need ANSI C limits.h to determine sizes */
+# include <limits.h>
+# define BYFOUR
+# if (UINT_MAX == 0xffffffffUL)
+ typedef unsigned int u4;
+# else
+# if (ULONG_MAX == 0xffffffffUL)
+ typedef unsigned long u4;
+# else
+# if (USHRT_MAX == 0xffffffffUL)
+ typedef unsigned short u4;
+# else
+# undef BYFOUR /* can't find a four-byte integer type! */
+# endif
+# endif
+# endif
+# endif /* STDC */
+#endif /* !NOBYFOUR */
+
+/* Definitions for doing the crc four data bytes at a time. */
+#ifdef BYFOUR
+# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
+ (((w)&0xff00)<<8)+(((w)&0xff)<<24))
+ local unsigned long crc32_little OF((unsigned long,
+ const unsigned char FAR *, unsigned));
+ local unsigned long crc32_big OF((unsigned long,
+ const unsigned char FAR *, unsigned));
+# define TBLS 8
+#else
+# define TBLS 1
+#endif /* BYFOUR */
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local volatile int crc_table_empty = 1;
+local unsigned long FAR crc_table[TBLS][256];
+local void make_crc_table OF((void));
+#ifdef MAKECRCH
+ local void write_table OF((FILE *, const unsigned long FAR *));
+#endif /* MAKECRCH */
+
+/*
+ Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+ x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+ Polynomials over GF(2) are represented in binary, one bit per coefficient,
+ with the lowest powers in the most significant bit. Then adding polynomials
+ is just exclusive-or, and multiplying a polynomial by x is a right shift by
+ one. If we call the above polynomial p, and represent a byte as the
+ polynomial q, also with the lowest power in the most significant bit (so the
+ byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+ where a mod b means the remainder after dividing a by b.
+
+ This calculation is done using the shift-register method of multiplying and
+ taking the remainder. The register is initialized to zero, and for each
+ incoming bit, x^32 is added mod p to the register if the bit is a one (where
+ x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+ x (which is shifting right by one and adding x^32 mod p if the bit shifted
+ out is a one). We start with the highest power (least significant bit) of
+ q and repeat for all eight bits of q.
+
+ The first table is simply the CRC of all possible eight bit values. This is
+ all the information needed to generate CRCs on data a byte at a time for all
+ combinations of CRC register values and incoming bytes. The remaining tables
+ allow for word-at-a-time CRC calculation for both big-endian and little-
+ endian machines, where a word is four bytes.
+*/
+local void make_crc_table()
+{
+ unsigned long c;
+ int n, k;
+ unsigned long poly; /* polynomial exclusive-or pattern */
+ /* terms of polynomial defining this crc (except x^32): */
+ static volatile int first = 1; /* flag to limit concurrent making */
+ static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+ /* See if another task is already doing this (not thread-safe, but better
+ than nothing -- significantly reduces duration of vulnerability in
+ case the advice about DYNAMIC_CRC_TABLE is ignored) */
+ if (first) {
+ first = 0;
+
+ /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+ poly = 0UL;
+ for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
+ poly |= 1UL << (31 - p[n]);
+
+ /* generate a crc for every 8-bit value */
+ for (n = 0; n < 256; n++) {
+ c = (unsigned long)n;
+ for (k = 0; k < 8; k++)
+ c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+ crc_table[0][n] = c;
+ }
+
+#ifdef BYFOUR
+ /* generate crc for each value followed by one, two, and three zeros,
+ and then the byte reversal of those as well as the first table */
+ for (n = 0; n < 256; n++) {
+ c = crc_table[0][n];
+ crc_table[4][n] = REV(c);
+ for (k = 1; k < 4; k++) {
+ c = crc_table[0][c & 0xff] ^ (c >> 8);
+ crc_table[k][n] = c;
+ crc_table[k + 4][n] = REV(c);
+ }
+ }
+#endif /* BYFOUR */
+
+ crc_table_empty = 0;
+ }
+ else { /* not first */
+ /* wait for the other guy to finish (not efficient, but rare) */
+ while (crc_table_empty)
+ ;
+ }
+
+#ifdef MAKECRCH
+ /* write out CRC tables to crc32.h */
+ {
+ FILE *out;
+
+ out = fopen("crc32.h", "w");
+ if (out == NULL) return;
+ fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
+ fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
+ fprintf(out, "local const unsigned long FAR ");
+ fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
+ write_table(out, crc_table[0]);
+# ifdef BYFOUR
+ fprintf(out, "#ifdef BYFOUR\n");
+ for (k = 1; k < 8; k++) {
+ fprintf(out, " },\n {\n");
+ write_table(out, crc_table[k]);
+ }
+ fprintf(out, "#endif\n");
+# endif /* BYFOUR */
+ fprintf(out, " }\n};\n");
+ fclose(out);
+ }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+local void write_table(out, table)
+ FILE *out;
+ const unsigned long FAR *table;
+{
+ int n;
+
+ for (n = 0; n < 256; n++)
+ fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
+ n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
+}
+#endif /* MAKECRCH */
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables of CRC-32s of all single-byte values, made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const unsigned long FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+ return (const unsigned long FAR *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
+{
+ if (buf == Z_NULL) return 0UL;
+
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+#ifdef BYFOUR
+ if (sizeof(void *) == sizeof(ptrdiff_t)) {
+ u4 endian;
+
+ endian = 1;
+ if (*((unsigned char *)(&endian)))
+ return crc32_little(crc, buf, len);
+ else
+ return crc32_big(crc, buf, len);
+ }
+#endif /* BYFOUR */
+ crc = crc ^ 0xffffffffUL;
+ while (len >= 8) {
+ DO8;
+ len -= 8;
+ }
+ if (len) do {
+ DO1;
+ } while (--len);
+ return crc ^ 0xffffffffUL;
+}
+
+#ifdef BYFOUR
+
+/* ========================================================================= */
+#define DOLIT4 c ^= *buf4++; \
+ c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
+ crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
+#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
+
+/* ========================================================================= */
+local unsigned long crc32_little(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
+{
+ register u4 c;
+ register const u4 FAR *buf4;
+
+ c = (u4)crc;
+ c = ~c;
+ while (len && ((ptrdiff_t)buf & 3)) {
+ c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+ len--;
+ }
+
+ buf4 = (const u4 FAR *)buf;
+ while (len >= 32) {
+ DOLIT32;
+ len -= 32;
+ }
+ while (len >= 4) {
+ DOLIT4;
+ len -= 4;
+ }
+ buf = (const unsigned char FAR *)buf4;
+
+ if (len) do {
+ c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+ } while (--len);
+ c = ~c;
+ return (unsigned long)c;
+}
+
+/* ========================================================================= */
+#define DOBIG4 c ^= *++buf4; \
+ c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
+ crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
+#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+
+/* ========================================================================= */
+local unsigned long crc32_big(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
+{
+ register u4 c;
+ register const u4 FAR *buf4;
+
+ c = REV((u4)crc);
+ c = ~c;
+ while (len && ((ptrdiff_t)buf & 3)) {
+ c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+ len--;
+ }
+
+ buf4 = (const u4 FAR *)buf;
+ buf4--;
+ while (len >= 32) {
+ DOBIG32;
+ len -= 32;
+ }
+ while (len >= 4) {
+ DOBIG4;
+ len -= 4;
+ }
+ buf4++;
+ buf = (const unsigned char FAR *)buf4;
+
+ if (len) do {
+ c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+ } while (--len);
+ c = ~c;
+ return (unsigned long)(REV(c));
+}
+
+#endif /* BYFOUR */
diff --git a/src/zlib/crc32.h b/src/zlib/crc32.h
new file mode 100644
index 000000000..8053b6117
--- /dev/null
+++ b/src/zlib/crc32.h
@@ -0,0 +1,441 @@
+/* crc32.h -- tables for rapid CRC calculation
+ * Generated automatically by crc32.c
+ */
+
+local const unsigned long FAR crc_table[TBLS][256] =
+{
+ {
+ 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+ 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+ 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+ 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+ 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+ 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+ 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+ 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+ 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+ 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+ 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+ 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+ 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+ 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+ 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+ 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+ 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+ 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+ 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+ 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+ 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+ 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+ 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+ 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+ 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+ 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+ 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+ 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+ 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+ 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+ 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+ 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+ 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+ 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+ 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+ 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+ 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+ 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+ 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+ 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+ 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+ 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+ 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+ 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+ 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+ 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+ 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+ 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+ 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+ 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+ 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+ 0x2d02ef8dUL
+#ifdef BYFOUR
+ },
+ {
+ 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
+ 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
+ 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
+ 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
+ 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
+ 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
+ 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
+ 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
+ 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
+ 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
+ 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
+ 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
+ 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
+ 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
+ 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
+ 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
+ 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
+ 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
+ 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
+ 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
+ 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
+ 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
+ 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
+ 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
+ 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
+ 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
+ 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
+ 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
+ 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
+ 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
+ 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
+ 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
+ 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
+ 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
+ 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
+ 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
+ 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
+ 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
+ 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
+ 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
+ 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
+ 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
+ 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
+ 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
+ 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
+ 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
+ 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
+ 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
+ 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
+ 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
+ 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
+ 0x9324fd72UL
+ },
+ {
+ 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
+ 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
+ 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
+ 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
+ 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
+ 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
+ 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
+ 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
+ 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
+ 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
+ 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
+ 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
+ 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
+ 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
+ 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
+ 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
+ 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
+ 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
+ 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
+ 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
+ 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
+ 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
+ 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
+ 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
+ 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
+ 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
+ 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
+ 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
+ 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
+ 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
+ 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
+ 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
+ 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
+ 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
+ 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
+ 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
+ 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
+ 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
+ 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
+ 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
+ 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
+ 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
+ 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
+ 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
+ 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
+ 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
+ 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
+ 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
+ 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
+ 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
+ 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
+ 0xbe9834edUL
+ },
+ {
+ 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
+ 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
+ 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
+ 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
+ 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
+ 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
+ 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
+ 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
+ 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
+ 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
+ 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
+ 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
+ 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
+ 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
+ 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
+ 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
+ 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
+ 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
+ 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
+ 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
+ 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
+ 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
+ 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
+ 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
+ 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
+ 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
+ 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
+ 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
+ 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
+ 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
+ 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
+ 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
+ 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
+ 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
+ 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
+ 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
+ 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
+ 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
+ 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
+ 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
+ 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
+ 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
+ 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
+ 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
+ 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
+ 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
+ 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
+ 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
+ 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
+ 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
+ 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
+ 0xde0506f1UL
+ },
+ {
+ 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
+ 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
+ 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
+ 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
+ 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
+ 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
+ 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
+ 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
+ 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
+ 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
+ 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
+ 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
+ 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
+ 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
+ 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
+ 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
+ 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
+ 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
+ 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
+ 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
+ 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
+ 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
+ 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
+ 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
+ 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
+ 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
+ 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
+ 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
+ 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
+ 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
+ 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
+ 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
+ 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
+ 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
+ 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
+ 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
+ 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
+ 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
+ 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
+ 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
+ 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
+ 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
+ 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
+ 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
+ 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
+ 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
+ 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
+ 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
+ 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
+ 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
+ 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
+ 0x8def022dUL
+ },
+ {
+ 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
+ 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
+ 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
+ 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
+ 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
+ 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
+ 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
+ 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
+ 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
+ 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
+ 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
+ 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
+ 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
+ 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
+ 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
+ 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
+ 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
+ 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
+ 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
+ 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
+ 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
+ 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
+ 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
+ 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
+ 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
+ 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
+ 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
+ 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
+ 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
+ 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
+ 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
+ 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
+ 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
+ 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
+ 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
+ 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
+ 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
+ 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
+ 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
+ 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
+ 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
+ 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
+ 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
+ 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
+ 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
+ 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
+ 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
+ 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
+ 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
+ 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
+ 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
+ 0x72fd2493UL
+ },
+ {
+ 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
+ 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
+ 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
+ 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
+ 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
+ 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
+ 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
+ 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
+ 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
+ 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
+ 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
+ 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
+ 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
+ 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
+ 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
+ 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
+ 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
+ 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
+ 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
+ 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
+ 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
+ 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
+ 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
+ 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
+ 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
+ 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
+ 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
+ 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
+ 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
+ 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
+ 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
+ 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
+ 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
+ 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
+ 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
+ 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
+ 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
+ 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
+ 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
+ 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
+ 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
+ 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
+ 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
+ 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
+ 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
+ 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
+ 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
+ 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
+ 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
+ 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
+ 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
+ 0xed3498beUL
+ },
+ {
+ 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
+ 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
+ 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
+ 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
+ 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
+ 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
+ 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
+ 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
+ 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
+ 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
+ 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
+ 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
+ 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
+ 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
+ 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
+ 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
+ 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
+ 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
+ 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
+ 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
+ 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
+ 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
+ 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
+ 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
+ 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
+ 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
+ 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
+ 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
+ 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
+ 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
+ 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
+ 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
+ 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
+ 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
+ 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
+ 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
+ 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
+ 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
+ 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
+ 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
+ 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
+ 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
+ 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
+ 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
+ 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
+ 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
+ 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
+ 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
+ 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
+ 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
+ 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
+ 0xf10605deUL
+#endif
+ }
+};
diff --git a/src/zlib/deflate.c b/src/zlib/deflate.c
new file mode 100644
index 000000000..0fc53bc1e
--- /dev/null
+++ b/src/zlib/deflate.c
@@ -0,0 +1,1502 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2004 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process depends on being able to identify portions
+ * of the input text which are identical to earlier input (within a
+ * sliding window trailing behind the input currently being processed).
+ *
+ * The most straightforward technique turns out to be the fastest for
+ * most input files: try all possible matches and select the longest.
+ * The key feature of this algorithm is that insertions into the string
+ * dictionary are very simple and thus fast, and deletions are avoided
+ * completely. Insertions are performed at each input character, whereas
+ * string matches are performed only when the previous match ends. So it
+ * is preferable to spend more time in matches to allow very fast string
+ * insertions and avoid deletions. The matching algorithm for small
+ * strings is inspired from that of Rabin & Karp. A brute force approach
+ * is used to find longer strings when a small match has been found.
+ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ * (by Leonid Broukhis).
+ * A previous version of this file used a more sophisticated algorithm
+ * (by Fiala and Greene) which is guaranteed to run in linear amortized
+ * time, but has a larger average cost, uses more memory and is patented.
+ * However the F&G algorithm may be faster for some highly redundant
+ * files if the parameter max_chain_length (described below) is too large.
+ *
+ * ACKNOWLEDGEMENTS
+ *
+ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ * I found it in 'freeze' written by Leonid Broukhis.
+ * Thanks to many people for bug reports and testing.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ * Available in http://www.ietf.org/rfc/rfc1951.txt
+ *
+ * A description of the Rabin and Karp algorithm is given in the book
+ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ * Fiala,E.R., and Greene,D.H.
+ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id$ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+ " deflate 1.2.2 Copyright 1995-2004 Jean-loup Gailly ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ * Function prototypes.
+ */
+typedef enum {
+ need_more, /* block not completed, need more input or more output */
+ block_done, /* block flush performed */
+ finish_started, /* finish started, need only more output at next deflate */
+ finish_done /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast OF((deflate_state *s, int flush));
+#ifndef FASTEST
+local block_state deflate_slow OF((deflate_state *s, int flush));
+#endif
+local void lm_init OF((deflate_state *s));
+local void putShortMSB OF((deflate_state *s, uInt b));
+local void flush_pending OF((z_streamp strm));
+local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifndef FASTEST
+#ifdef ASMV
+ void match_init OF((void)); /* asm code initialization */
+ uInt longest_match OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match OF((deflate_state *s, IPos cur_match));
+#endif
+#endif
+local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
+
+#ifdef DEBUG
+local void check_match OF((deflate_state *s, IPos start, IPos match,
+ int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+# define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+ ush good_length; /* reduce lazy search above this match length */
+ ush max_lazy; /* do not perform lazy search above this match length */
+ ush nice_length; /* quit search above this match length */
+ ush max_chain;
+ compress_func func;
+} config;
+
+#ifdef FASTEST
+local const config configuration_table[2] = {
+/* good lazy nice chain */
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
+/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
+#else
+local const config configuration_table[10] = {
+/* good lazy nice chain */
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
+/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
+/* 2 */ {4, 5, 16, 8, deflate_fast},
+/* 3 */ {4, 6, 32, 32, deflate_fast},
+
+/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
+/* 5 */ {8, 16, 32, 32, deflate_slow},
+/* 6 */ {8, 16, 128, 128, deflate_slow},
+/* 7 */ {8, 32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
+#endif
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+#ifndef NO_DUMMY_DECL
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+#endif
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN assertion: all calls to to UPDATE_HASH are made with consecutive
+ * input characters, so that a running hash key can be computed from the
+ * previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN assertion: all calls to to INSERT_STRING are made with consecutive
+ * input characters and the first MIN_MATCH bytes of str are valid
+ * (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+ s->head[s->hash_size-1] = NIL; \
+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+ z_streamp strm;
+ int level;
+ const char *version;
+ int stream_size;
+{
+ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+ Z_DEFAULT_STRATEGY, version, stream_size);
+ /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+ version, stream_size)
+ z_streamp strm;
+ int level;
+ int method;
+ int windowBits;
+ int memLevel;
+ int strategy;
+ const char *version;
+ int stream_size;
+{
+ deflate_state *s;
+ int wrap = 1;
+ static const char my_version[] = ZLIB_VERSION;
+
+ ushf *overlay;
+ /* We overlay pending_buf and d_buf+l_buf. This works since the average
+ * output size for (length,distance) codes is <= 24 bits.
+ */
+
+ if (version == Z_NULL || version[0] != my_version[0] ||
+ stream_size != sizeof(z_stream)) {
+ return Z_VERSION_ERROR;
+ }
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+ strm->msg = Z_NULL;
+ if (strm->zalloc == (alloc_func)0) {
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+ }
+ if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+
+#ifdef FASTEST
+ if (level != 0) level = 1;
+#else
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+
+ if (windowBits < 0) { /* suppress zlib wrapper */
+ wrap = 0;
+ windowBits = -windowBits;
+ }
+#ifdef GZIP
+ else if (windowBits > 15) {
+ wrap = 2; /* write gzip wrapper instead */
+ windowBits -= 16;
+ }
+#endif
+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+ windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+ strategy < 0 || strategy > Z_RLE) {
+ return Z_STREAM_ERROR;
+ }
+ if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+ if (s == Z_NULL) return Z_MEM_ERROR;
+ strm->state = (struct internal_state FAR *)s;
+ s->strm = strm;
+
+ s->wrap = wrap;
+ s->w_bits = windowBits;
+ s->w_size = 1 << s->w_bits;
+ s->w_mask = s->w_size - 1;
+
+ s->hash_bits = memLevel + 7;
+ s->hash_size = 1 << s->hash_bits;
+ s->hash_mask = s->hash_size - 1;
+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+ s->pending_buf = (uchf *) overlay;
+ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+ s->pending_buf == Z_NULL) {
+ s->status = FINISH_STATE;
+ strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
+ deflateEnd (strm);
+ return Z_MEM_ERROR;
+ }
+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+ s->level = level;
+ s->strategy = strategy;
+ s->method = (Byte)method;
+
+ return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+ z_streamp strm;
+ const Bytef *dictionary;
+ uInt dictLength;
+{
+ deflate_state *s;
+ uInt length = dictLength;
+ uInt n;
+ IPos hash_head = 0;
+
+ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
+ strm->state->wrap == 2 ||
+ (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
+ return Z_STREAM_ERROR;
+
+ s = strm->state;
+ if (s->wrap)
+ strm->adler = adler32(strm->adler, dictionary, dictLength);
+
+ if (length < MIN_MATCH) return Z_OK;
+ if (length > MAX_DIST(s)) {
+ length = MAX_DIST(s);
+#ifndef USE_DICT_HEAD
+ dictionary += dictLength - length; /* use the tail of the dictionary */
+#endif
+ }
+ zmemcpy(s->window, dictionary, length);
+ s->strstart = length;
+ s->block_start = (long)length;
+
+ /* Insert all strings in the hash table (except for the last two bytes).
+ * s->lookahead stays null, so s->ins_h will be recomputed at the next
+ * call of fill_window.
+ */
+ s->ins_h = s->window[0];
+ UPDATE_HASH(s, s->ins_h, s->window[1]);
+ for (n = 0; n <= length - MIN_MATCH; n++) {
+ INSERT_STRING(s, n, hash_head);
+ }
+ if (hash_head) hash_head = 0; /* to make compiler happy */
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+ z_streamp strm;
+{
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL ||
+ strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
+ return Z_STREAM_ERROR;
+ }
+
+ strm->total_in = strm->total_out = 0;
+ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+ strm->data_type = Z_UNKNOWN;
+
+ s = (deflate_state *)strm->state;
+ s->pending = 0;
+ s->pending_out = s->pending_buf;
+
+ if (s->wrap < 0) {
+ s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
+ }
+ s->status = s->wrap ? INIT_STATE : BUSY_STATE;
+ strm->adler =
+#ifdef GZIP
+ s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
+#endif
+ adler32(0L, Z_NULL, 0);
+ s->last_flush = Z_NO_FLUSH;
+
+ _tr_init(s);
+ lm_init(s);
+
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePrime (strm, bits, value)
+ z_streamp strm;
+ int bits;
+ int value;
+{
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ strm->state->bi_valid = bits;
+ strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+ z_streamp strm;
+ int level;
+ int strategy;
+{
+ deflate_state *s;
+ compress_func func;
+ int err = Z_OK;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ s = strm->state;
+
+#ifdef FASTEST
+ if (level != 0) level = 1;
+#else
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_RLE) {
+ return Z_STREAM_ERROR;
+ }
+ func = configuration_table[s->level].func;
+
+ if (func != configuration_table[level].func && strm->total_in != 0) {
+ /* Flush the last buffer: */
+ err = deflate(strm, Z_PARTIAL_FLUSH);
+ }
+ if (s->level != level) {
+ s->level = level;
+ s->max_lazy_match = configuration_table[level].max_lazy;
+ s->good_match = configuration_table[level].good_length;
+ s->nice_match = configuration_table[level].nice_length;
+ s->max_chain_length = configuration_table[level].max_chain;
+ }
+ s->strategy = strategy;
+ return err;
+}
+
+/* =========================================================================
+ * For the default windowBits of 15 and memLevel of 8, this function returns
+ * a close to exact, as well as small, upper bound on the compressed size.
+ * They are coded as constants here for a reason--if the #define's are
+ * changed, then this function needs to be changed as well. The return
+ * value for 15 and 8 only works for those exact settings.
+ *
+ * For any setting other than those defaults for windowBits and memLevel,
+ * the value returned is a conservative worst case for the maximum expansion
+ * resulting from using fixed blocks instead of stored blocks, which deflate
+ * can emit on compressed data for some combinations of the parameters.
+ *
+ * This function could be more sophisticated to provide closer upper bounds
+ * for every combination of windowBits and memLevel, as well as wrap.
+ * But even the conservative upper bound of about 14% expansion does not
+ * seem onerous for output buffer allocation.
+ */
+uLong ZEXPORT deflateBound(strm, sourceLen)
+ z_streamp strm;
+ uLong sourceLen;
+{
+ deflate_state *s;
+ uLong destLen;
+
+ /* conservative upper bound */
+ destLen = sourceLen +
+ ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
+
+ /* if can't get parameters, return conservative bound */
+ if (strm == Z_NULL || strm->state == Z_NULL)
+ return destLen;
+
+ /* if not default parameters, return conservative bound */
+ s = strm->state;
+ if (s->w_bits != 15 || s->hash_bits != 8 + 7)
+ return destLen;
+
+ /* default settings: return tight bound for that case */
+ return compressBound(sourceLen);
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+ deflate_state *s;
+ uInt b;
+{
+ put_byte(s, (Byte)(b >> 8));
+ put_byte(s, (Byte)(b & 0xff));
+}
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+ z_streamp strm;
+{
+ unsigned len = strm->state->pending;
+
+ if (len > strm->avail_out) len = strm->avail_out;
+ if (len == 0) return;
+
+ zmemcpy(strm->next_out, strm->state->pending_out, len);
+ strm->next_out += len;
+ strm->state->pending_out += len;
+ strm->total_out += len;
+ strm->avail_out -= len;
+ strm->state->pending -= len;
+ if (strm->state->pending == 0) {
+ strm->state->pending_out = strm->state->pending_buf;
+ }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+ z_streamp strm;
+ int flush;
+{
+ int old_flush; /* value of flush param for previous deflate call */
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL ||
+ flush > Z_FINISH || flush < 0) {
+ return Z_STREAM_ERROR;
+ }
+ s = strm->state;
+
+ if (strm->next_out == Z_NULL ||
+ (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+ (s->status == FINISH_STATE && flush != Z_FINISH)) {
+ ERR_RETURN(strm, Z_STREAM_ERROR);
+ }
+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+ s->strm = strm; /* just in case */
+ old_flush = s->last_flush;
+ s->last_flush = flush;
+
+ /* Write the header */
+ if (s->status == INIT_STATE) {
+#ifdef GZIP
+ if (s->wrap == 2) {
+ put_byte(s, 31);
+ put_byte(s, 139);
+ put_byte(s, 8);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, s->level == 9 ? 2 :
+ (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+ 4 : 0));
+ put_byte(s, 255);
+ s->status = BUSY_STATE;
+ strm->adler = crc32(0L, Z_NULL, 0);
+ }
+ else
+#endif
+ {
+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+ uInt level_flags;
+
+ if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
+ level_flags = 0;
+ else if (s->level < 6)
+ level_flags = 1;
+ else if (s->level == 6)
+ level_flags = 2;
+ else
+ level_flags = 3;
+ header |= (level_flags << 6);
+ if (s->strstart != 0) header |= PRESET_DICT;
+ header += 31 - (header % 31);
+
+ s->status = BUSY_STATE;
+ putShortMSB(s, header);
+
+ /* Save the adler32 of the preset dictionary: */
+ if (s->strstart != 0) {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ strm->adler = adler32(0L, Z_NULL, 0);
+ }
+ }
+
+ /* Flush as much pending output as possible */
+ if (s->pending != 0) {
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ /* Since avail_out is 0, deflate will be called again with
+ * more output space, but possibly with both pending and
+ * avail_in equal to zero. There won't be anything to do,
+ * but this is not an error situation so make sure we
+ * return OK instead of BUF_ERROR at next call of deflate:
+ */
+ s->last_flush = -1;
+ return Z_OK;
+ }
+
+ /* Make sure there is something to do and avoid duplicate consecutive
+ * flushes. For repeated and useless calls with Z_FINISH, we keep
+ * returning Z_STREAM_END instead of Z_BUF_ERROR.
+ */
+ } else if (strm->avail_in == 0 && flush <= old_flush &&
+ flush != Z_FINISH) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* User must not provide more input after the first FINISH: */
+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* Start a new block or continue the current one.
+ */
+ if (strm->avail_in != 0 || s->lookahead != 0 ||
+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+ block_state bstate;
+
+ bstate = (*(configuration_table[s->level].func))(s, flush);
+
+ if (bstate == finish_started || bstate == finish_done) {
+ s->status = FINISH_STATE;
+ }
+ if (bstate == need_more || bstate == finish_started) {
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+ }
+ return Z_OK;
+ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+ * of deflate should use the same flush parameter to make sure
+ * that the flush is complete. So we don't have to output an
+ * empty block here, this will be done at next call. This also
+ * ensures that for a very small output buffer, we emit at most
+ * one empty block.
+ */
+ }
+ if (bstate == block_done) {
+ if (flush == Z_PARTIAL_FLUSH) {
+ _tr_align(s);
+ } else { /* FULL_FLUSH or SYNC_FLUSH */
+ _tr_stored_block(s, (char*)0, 0L, 0);
+ /* For a full flush, this empty block will be recognized
+ * as a special marker by inflate_sync().
+ */
+ if (flush == Z_FULL_FLUSH) {
+ CLEAR_HASH(s); /* forget history */
+ }
+ }
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+ return Z_OK;
+ }
+ }
+ }
+ Assert(strm->avail_out > 0, "bug2");
+
+ if (flush != Z_FINISH) return Z_OK;
+ if (s->wrap <= 0) return Z_STREAM_END;
+
+ /* Write the trailer */
+#ifdef GZIP
+ if (s->wrap == 2) {
+ put_byte(s, (Byte)(strm->adler & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
+ put_byte(s, (Byte)(strm->total_in & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
+ }
+ else
+#endif
+ {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ flush_pending(strm);
+ /* If avail_out is zero, the application will call deflate again
+ * to flush the rest.
+ */
+ if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
+ return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+ z_streamp strm;
+{
+ int status;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+ status = strm->state->status;
+ if (status != INIT_STATE && status != BUSY_STATE &&
+ status != FINISH_STATE) {
+ return Z_STREAM_ERROR;
+ }
+
+ /* Deallocate in reverse order of allocations: */
+ TRY_FREE(strm, strm->state->pending_buf);
+ TRY_FREE(strm, strm->state->head);
+ TRY_FREE(strm, strm->state->prev);
+ TRY_FREE(strm, strm->state->window);
+
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+
+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+ z_streamp dest;
+ z_streamp source;
+{
+#ifdef MAXSEG_64K
+ return Z_STREAM_ERROR;
+#else
+ deflate_state *ds;
+ deflate_state *ss;
+ ushf *overlay;
+
+
+ if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+ return Z_STREAM_ERROR;
+ }
+
+ ss = source->state;
+
+ *dest = *source;
+
+ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+ if (ds == Z_NULL) return Z_MEM_ERROR;
+ dest->state = (struct internal_state FAR *) ds;
+ *ds = *ss;
+ ds->strm = dest;
+
+ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
+ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
+ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+ ds->pending_buf = (uchf *) overlay;
+
+ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+ ds->pending_buf == Z_NULL) {
+ deflateEnd (dest);
+ return Z_MEM_ERROR;
+ }
+ /* following zmemcpy do not work for 16-bit MSDOS */
+ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+ zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
+ zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+ ds->l_desc.dyn_tree = ds->dyn_ltree;
+ ds->d_desc.dyn_tree = ds->dyn_dtree;
+ ds->bl_desc.dyn_tree = ds->bl_tree;
+
+ return Z_OK;
+#endif /* MAXSEG_64K */
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read. All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+ z_streamp strm;
+ Bytef *buf;
+ unsigned size;
+{
+ unsigned len = strm->avail_in;
+
+ if (len > size) len = size;
+ if (len == 0) return 0;
+
+ strm->avail_in -= len;
+
+ if (strm->state->wrap == 1) {
+ strm->adler = adler32(strm->adler, strm->next_in, len);
+ }
+#ifdef GZIP
+ else if (strm->state->wrap == 2) {
+ strm->adler = crc32(strm->adler, strm->next_in, len);
+ }
+#endif
+ zmemcpy(buf, strm->next_in, len);
+ strm->next_in += len;
+ strm->total_in += len;
+
+ return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+ deflate_state *s;
+{
+ s->window_size = (ulg)2L*s->w_size;
+
+ CLEAR_HASH(s);
+
+ /* Set the default configuration parameters:
+ */
+ s->max_lazy_match = configuration_table[s->level].max_lazy;
+ s->good_match = configuration_table[s->level].good_length;
+ s->nice_match = configuration_table[s->level].nice_length;
+ s->max_chain_length = configuration_table[s->level].max_chain;
+
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->lookahead = 0;
+ s->match_length = s->prev_length = MIN_MATCH-1;
+ s->match_available = 0;
+ s->ins_h = 0;
+#ifdef ASMV
+ match_init(); /* initialize the asm code */
+#endif
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local uInt longest_match(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ unsigned chain_length = s->max_chain_length;/* max hash chain length */
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ int best_len = s->prev_length; /* best match length so far */
+ int nice_match = s->nice_match; /* stop if match long enough */
+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+ s->strstart - (IPos)MAX_DIST(s) : NIL;
+ /* Stop when cur_match becomes <= limit. To simplify the code,
+ * we prevent matches with the string of window index 0.
+ */
+ Posf *prev = s->prev;
+ uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+ /* Compare two bytes at a time. Note: this is not always beneficial.
+ * Try with and without -DUNALIGNED_OK to check.
+ */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+ register ush scan_start = *(ushf*)scan;
+ register ush scan_end = *(ushf*)(scan+best_len-1);
+#else
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+ register Byte scan_end1 = scan[best_len-1];
+ register Byte scan_end = scan[best_len];
+#endif
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ /* Do not waste too much time if we already have a good match: */
+ if (s->prev_length >= s->good_match) {
+ chain_length >>= 2;
+ }
+ /* Do not look for matches beyond the end of the input. This is necessary
+ * to make deflate deterministic.
+ */
+ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ do {
+ Assert(cur_match < s->strstart, "no future");
+ match = s->window + cur_match;
+
+ /* Skip to next match if the match length cannot increase
+ * or if the match length is less than 2:
+ */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+ /* This code assumes sizeof(unsigned short) == 2. Do not use
+ * UNALIGNED_OK if your compiler uses a different size.
+ */
+ if (*(ushf*)(match+best_len-1) != scan_end ||
+ *(ushf*)match != scan_start) continue;
+
+ /* It is not necessary to compare scan[2] and match[2] since they are
+ * always equal when the other bytes match, given that the hash keys
+ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+ * strstart+3, +5, ... up to strstart+257. We check for insufficient
+ * lookahead only every 4th comparison; the 128th check will be made
+ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+ * necessary to put more guard bytes at the end of the window, or
+ * to check more often for insufficient lookahead.
+ */
+ Assert(scan[2] == match[2], "scan[2]?");
+ scan++, match++;
+ do {
+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ scan < strend);
+ /* The funny "do {}" generates better code on most compilers */
+
+ /* Here, scan <= window+strstart+257 */
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+ if (*scan == *match) scan++;
+
+ len = (MAX_MATCH - 1) - (int)(strend-scan);
+ scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+ if (match[best_len] != scan_end ||
+ match[best_len-1] != scan_end1 ||
+ *match != *scan ||
+ *++match != scan[1]) continue;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match++;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+ scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+ if (len > best_len) {
+ s->match_start = cur_match;
+ best_len = len;
+ if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+ scan_end = *(ushf*)(scan+best_len-1);
+#else
+ scan_end1 = scan[best_len-1];
+ scan_end = scan[best_len];
+#endif
+ }
+ } while ((cur_match = prev[cur_match & wmask]) > limit
+ && --chain_length != 0);
+
+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+ return s->lookahead;
+}
+#endif /* ASMV */
+#endif /* FASTEST */
+
+/* ---------------------------------------------------------------------------
+ * Optimized version for level == 1 or strategy == Z_RLE only
+ */
+local uInt longest_match_fast(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ Assert(cur_match < s->strstart, "no future");
+
+ match = s->window + cur_match;
+
+ /* Return failure if the match length is less than 2:
+ */
+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match += 2;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+
+ if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+ s->match_start = cur_match;
+ return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
+}
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+ deflate_state *s;
+ IPos start, match;
+ int length;
+{
+ /* check that the match is indeed a match */
+ if (zmemcmp(s->window + match,
+ s->window + start, length) != EQUAL) {
+ fprintf(stderr, " start %u, match %u, length %d\n",
+ start, match, length);
+ do {
+ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+ } while (--length != 0);
+ z_error("invalid match");
+ }
+ if (z_verbose > 1) {
+ fprintf(stderr,"\\[%d,%d]", start-match, length);
+ do { putc(s->window[start++], stderr); } while (--length != 0);
+ }
+}
+#else
+# define check_match(s, start, match, length)
+#endif /* DEBUG */
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ * At least one byte has been read, or avail_in == 0; reads are
+ * performed for at least two bytes (required for the zip translate_eol
+ * option -- not supported here).
+ */
+local void fill_window(s)
+ deflate_state *s;
+{
+ register unsigned n, m;
+ register Posf *p;
+ unsigned more; /* Amount of free space at the end of the window. */
+ uInt wsize = s->w_size;
+
+ do {
+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+ /* Deal with !@#$% 64K limit: */
+ if (sizeof(int) <= 2) {
+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+ more = wsize;
+
+ } else if (more == (unsigned)(-1)) {
+ /* Very unlikely, but possible on 16 bit machine if
+ * strstart == 0 && lookahead == 1 (input done a byte at time)
+ */
+ more--;
+ }
+ }
+
+ /* If the window is almost full and there is insufficient lookahead,
+ * move the upper half to the lower one to make room in the upper half.
+ */
+ if (s->strstart >= wsize+MAX_DIST(s)) {
+
+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+ s->match_start -= wsize;
+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
+ s->block_start -= (long) wsize;
+
+ /* Slide the hash table (could be avoided with 32 bit values
+ at the expense of memory usage). We slide even when level == 0
+ to keep the hash table consistent if we switch back to level > 0
+ later. (Using level 0 permanently is not an optimal usage of
+ zlib, so we don't care about this pathological case.)
+ */
+ n = s->hash_size;
+ p = &s->head[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
+ } while (--n);
+
+ n = wsize;
+#ifndef FASTEST
+ p = &s->prev[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
+ /* If n is not on any hash chain, prev[n] is garbage but
+ * its value will never be used.
+ */
+ } while (--n);
+#endif
+ more += wsize;
+ }
+ if (s->strm->avail_in == 0) return;
+
+ /* If there was no sliding:
+ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+ * more == window_size - lookahead - strstart
+ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+ * => more >= window_size - 2*WSIZE + 2
+ * In the BIG_MEM or MMAP case (not yet supported),
+ * window_size == input_size + MIN_LOOKAHEAD &&
+ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+ * Otherwise, window_size == 2*WSIZE so more >= 2.
+ * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+ */
+ Assert(more >= 2, "more < 2");
+
+ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+ s->lookahead += n;
+
+ /* Initialize the hash value now that we have some input: */
+ if (s->lookahead >= MIN_MATCH) {
+ s->ins_h = s->window[s->strstart];
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ }
+ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+ * but this is not important since only literal bytes will be emitted.
+ */
+
+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, eof) { \
+ _tr_flush_block(s, (s->block_start >= 0L ? \
+ (charf *)&s->window[(unsigned)s->block_start] : \
+ (charf *)Z_NULL), \
+ (ulg)((long)s->strstart - s->block_start), \
+ (eof)); \
+ s->block_start = s->strstart; \
+ flush_pending(s->strm); \
+ Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, eof) { \
+ FLUSH_BLOCK_ONLY(s, eof); \
+ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+ * to pending_buf_size, and each stored block has a 5 byte header:
+ */
+ ulg max_block_size = 0xffff;
+ ulg max_start;
+
+ if (max_block_size > s->pending_buf_size - 5) {
+ max_block_size = s->pending_buf_size - 5;
+ }
+
+ /* Copy as much as possible from input to output: */
+ for (;;) {
+ /* Fill the window as much as possible: */
+ if (s->lookahead <= 1) {
+
+ Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+ s->block_start >= (long)s->w_size, "slide too late");
+
+ fill_window(s);
+ if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+ Assert(s->block_start >= 0L, "block gone");
+
+ s->strstart += s->lookahead;
+ s->lookahead = 0;
+
+ /* Emit a stored block if pending_buf will be full: */
+ max_start = s->block_start + max_block_size;
+ if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+ /* strstart == 0 is possible when wraparound on 16-bit machine */
+ s->lookahead = (uInt)(s->strstart - max_start);
+ s->strstart = (uInt)max_start;
+ FLUSH_BLOCK(s, 0);
+ }
+ /* Flush if we may have to slide, otherwise block_start may become
+ * negative and the data will be gone:
+ */
+ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+ FLUSH_BLOCK(s, 0);
+ }
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head = NIL; /* head of the hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ * At this point we have always match_length < MIN_MATCH
+ */
+ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+#ifdef FASTEST
+ if ((s->strategy < Z_HUFFMAN_ONLY) ||
+ (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
+ s->match_length = longest_match_fast (s, hash_head);
+ }
+#else
+ if (s->strategy < Z_HUFFMAN_ONLY) {
+ s->match_length = longest_match (s, hash_head);
+ } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
+ s->match_length = longest_match_fast (s, hash_head);
+ }
+#endif
+ /* longest_match() or longest_match_fast() sets match_start */
+ }
+ if (s->match_length >= MIN_MATCH) {
+ check_match(s, s->strstart, s->match_start, s->match_length);
+
+ _tr_tally_dist(s, s->strstart - s->match_start,
+ s->match_length - MIN_MATCH, bflush);
+
+ s->lookahead -= s->match_length;
+
+ /* Insert new strings in the hash table only if the match length
+ * is not too large. This saves time but degrades compression.
+ */
+#ifndef FASTEST
+ if (s->match_length <= s->max_insert_length &&
+ s->lookahead >= MIN_MATCH) {
+ s->match_length--; /* string at strstart already in table */
+ do {
+ s->strstart++;
+ INSERT_STRING(s, s->strstart, hash_head);
+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+ * always MIN_MATCH bytes ahead.
+ */
+ } while (--s->match_length != 0);
+ s->strstart++;
+ } else
+#endif
+ {
+ s->strstart += s->match_length;
+ s->match_length = 0;
+ s->ins_h = s->window[s->strstart];
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+ * matter since it will be recomputed at next deflate call.
+ */
+ }
+ } else {
+ /* No match, output a literal byte */
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ }
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head = NIL; /* head of hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ /* Process the input block. */
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ */
+ s->prev_length = s->match_length, s->prev_match = s->match_start;
+ s->match_length = MIN_MATCH-1;
+
+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+ s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+ if (s->strategy < Z_HUFFMAN_ONLY) {
+ s->match_length = longest_match (s, hash_head);
+ } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
+ s->match_length = longest_match_fast (s, hash_head);
+ }
+ /* longest_match() or longest_match_fast() sets match_start */
+
+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED
+#if TOO_FAR <= 32767
+ || (s->match_length == MIN_MATCH &&
+ s->strstart - s->match_start > TOO_FAR)
+#endif
+ )) {
+
+ /* If prev_match is also MIN_MATCH, match_start is garbage
+ * but we will ignore the current match anyway.
+ */
+ s->match_length = MIN_MATCH-1;
+ }
+ }
+ /* If there was a match at the previous step and the current
+ * match is not better, output the previous match:
+ */
+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+ /* Do not insert strings in hash table beyond this. */
+
+ check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+ _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+ s->prev_length - MIN_MATCH, bflush);
+
+ /* Insert in hash table all strings up to the end of the match.
+ * strstart-1 and strstart are already inserted. If there is not
+ * enough lookahead, the last two strings are not inserted in
+ * the hash table.
+ */
+ s->lookahead -= s->prev_length-1;
+ s->prev_length -= 2;
+ do {
+ if (++s->strstart <= max_insert) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+ } while (--s->prev_length != 0);
+ s->match_available = 0;
+ s->match_length = MIN_MATCH-1;
+ s->strstart++;
+
+ if (bflush) FLUSH_BLOCK(s, 0);
+
+ } else if (s->match_available) {
+ /* If there was no match at the previous position, output a
+ * single literal. If there was a match but the current match
+ * is longer, truncate the previous match to a single literal.
+ */
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ if (bflush) {
+ FLUSH_BLOCK_ONLY(s, 0);
+ }
+ s->strstart++;
+ s->lookahead--;
+ if (s->strm->avail_out == 0) return need_more;
+ } else {
+ /* There is no previous match to compare with, wait for
+ * the next step to decide.
+ */
+ s->match_available = 1;
+ s->strstart++;
+ s->lookahead--;
+ }
+ }
+ Assert (flush != Z_NO_FLUSH, "no flush?");
+ if (s->match_available) {
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ s->match_available = 0;
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+#endif /* FASTEST */
diff --git a/src/zlib/deflate.h b/src/zlib/deflate.h
new file mode 100644
index 000000000..410681d18
--- /dev/null
+++ b/src/zlib/deflate.h
@@ -0,0 +1,325 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2002 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef DEFLATE_H
+#define DEFLATE_H
+
+#include "zutil.h"
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+ trailer creation by deflate(). NO_GZIP would be used to avoid linking in
+ the crc code when it is not needed. For shared libraries, gzip encoding
+ should be left enabled. */
+#ifndef NO_GZIP
+# define GZIP
+#endif
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS 256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES 30
+/* number of distance codes */
+
+#define BL_CODES 19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define INIT_STATE 42
+#define BUSY_STATE 113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+ union {
+ ush freq; /* frequency count */
+ ush code; /* bit string */
+ } fc;
+ union {
+ ush dad; /* father node in Huffman tree */
+ ush len; /* length of bit string */
+ } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad dl.dad
+#define Len dl.len
+
+typedef struct static_tree_desc_s static_tree_desc;
+
+typedef struct tree_desc_s {
+ ct_data *dyn_tree; /* the dynamic tree */
+ int max_code; /* largest code with non zero frequency */
+ static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+ z_streamp strm; /* pointer back to this zlib stream */
+ int status; /* as the name implies */
+ Bytef *pending_buf; /* output still pending */
+ ulg pending_buf_size; /* size of pending_buf */
+ Bytef *pending_out; /* next pending byte to output to the stream */
+ int pending; /* nb of bytes in the pending buffer */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
+ Byte method; /* STORED (for zip only) or DEFLATED */
+ int last_flush; /* value of flush param for previous deflate call */
+
+ /* used by deflate.c: */
+
+ uInt w_size; /* LZ77 window size (32K by default) */
+ uInt w_bits; /* log2(w_size) (8..16) */
+ uInt w_mask; /* w_size - 1 */
+
+ Bytef *window;
+ /* Sliding window. Input bytes are read into the second half of the window,
+ * and move to the first half later to keep a dictionary of at least wSize
+ * bytes. With this organization, matches are limited to a distance of
+ * wSize-MAX_MATCH bytes, but this ensures that IO is always
+ * performed with a length multiple of the block size. Also, it limits
+ * the window size to 64K, which is quite useful on MSDOS.
+ * To do: use the user input buffer as sliding window.
+ */
+
+ ulg window_size;
+ /* Actual size of window: 2*wSize, except when the user input buffer
+ * is directly used as sliding window.
+ */
+
+ Posf *prev;
+ /* Link to older string with same hash index. To limit the size of this
+ * array to 64K, this link is maintained only for the last 32K strings.
+ * An index in this array is thus a window index modulo 32K.
+ */
+
+ Posf *head; /* Heads of the hash chains or NIL. */
+
+ uInt ins_h; /* hash index of string to be inserted */
+ uInt hash_size; /* number of elements in hash table */
+ uInt hash_bits; /* log2(hash_size) */
+ uInt hash_mask; /* hash_size-1 */
+
+ uInt hash_shift;
+ /* Number of bits by which ins_h must be shifted at each input
+ * step. It must be such that after MIN_MATCH steps, the oldest
+ * byte no longer takes part in the hash key, that is:
+ * hash_shift * MIN_MATCH >= hash_bits
+ */
+
+ long block_start;
+ /* Window position at the beginning of the current output block. Gets
+ * negative when the window is moved backwards.
+ */
+
+ uInt match_length; /* length of best match */
+ IPos prev_match; /* previous match */
+ int match_available; /* set if previous match exists */
+ uInt strstart; /* start of string to insert */
+ uInt match_start; /* start of matching string */
+ uInt lookahead; /* number of valid bytes ahead in window */
+
+ uInt prev_length;
+ /* Length of the best match at previous step. Matches not greater than this
+ * are discarded. This is used in the lazy match evaluation.
+ */
+
+ uInt max_chain_length;
+ /* To speed up deflation, hash chains are never searched beyond this
+ * length. A higher limit improves compression ratio but degrades the
+ * speed.
+ */
+
+ uInt max_lazy_match;
+ /* Attempt to find a better match only when the current match is strictly
+ * smaller than this value. This mechanism is used only for compression
+ * levels >= 4.
+ */
+# define max_insert_length max_lazy_match
+ /* Insert new strings in the hash table only if the match length is not
+ * greater than this length. This saves time but degrades compression.
+ * max_insert_length is used only for compression levels <= 3.
+ */
+
+ int level; /* compression level (1..9) */
+ int strategy; /* favor or force Huffman coding*/
+
+ uInt good_match;
+ /* Use a faster search when the previous match is longer than this */
+
+ int nice_match; /* Stop searching when current match exceeds this */
+
+ /* used by trees.c: */
+ /* Didn't use ct_data typedef below to supress compiler warning */
+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
+
+ struct tree_desc_s l_desc; /* desc. for literal tree */
+ struct tree_desc_s d_desc; /* desc. for distance tree */
+ struct tree_desc_s bl_desc; /* desc. for bit length tree */
+
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
+ int heap_len; /* number of elements in the heap */
+ int heap_max; /* element of largest frequency */
+ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+ * The same heap array is used to build all trees.
+ */
+
+ uch depth[2*L_CODES+1];
+ /* Depth of each subtree used as tie breaker for trees of equal frequency
+ */
+
+ uchf *l_buf; /* buffer for literals or lengths */
+
+ uInt lit_bufsize;
+ /* Size of match buffer for literals/lengths. There are 4 reasons for
+ * limiting lit_bufsize to 64K:
+ * - frequencies can be kept in 16 bit counters
+ * - if compression is not successful for the first block, all input
+ * data is still in the window so we can still emit a stored block even
+ * when input comes from standard input. (This can also be done for
+ * all blocks if lit_bufsize is not greater than 32K.)
+ * - if compression is not successful for a file smaller than 64K, we can
+ * even emit a stored file instead of a stored block (saving 5 bytes).
+ * This is applicable only for zip (not gzip or zlib).
+ * - creating new Huffman trees less frequently may not provide fast
+ * adaptation to changes in the input data statistics. (Take for
+ * example a binary file with poorly compressible code followed by
+ * a highly compressible string table.) Smaller buffer sizes give
+ * fast adaptation but have of course the overhead of transmitting
+ * trees more frequently.
+ * - I can't count above 4
+ */
+
+ uInt last_lit; /* running index in l_buf */
+
+ ushf *d_buf;
+ /* Buffer for distances. To simplify the code, d_buf and l_buf have
+ * the same number of elements. To use different lengths, an extra flag
+ * array would be necessary.
+ */
+
+ ulg opt_len; /* bit length of current block with optimal trees */
+ ulg static_len; /* bit length of current block with static trees */
+ uInt matches; /* number of string matches in current block */
+ int last_eob_len; /* bit length of EOB code for last block */
+
+#ifdef DEBUG
+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
+#endif
+
+ ush bi_buf;
+ /* Output buffer. bits are inserted starting at the bottom (least
+ * significant bits).
+ */
+ int bi_valid;
+ /* Number of valid bits in bi_buf. All bits above the last valid bit
+ * are always zero.
+ */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+ /* in trees.c */
+void _tr_init OF((deflate_state *s));
+int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
+ int eof));
+void _tr_align OF((deflate_state *s));
+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
+ int eof));
+
+#define d_code(dist) \
+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+ extern uch _length_code[];
+ extern uch _dist_code[];
+#else
+ extern const uch _length_code[];
+ extern const uch _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+ { uch cc = (c); \
+ s->d_buf[s->last_lit] = 0; \
+ s->l_buf[s->last_lit++] = cc; \
+ s->dyn_ltree[cc].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+# define _tr_tally_dist(s, distance, length, flush) \
+ { uch len = (length); \
+ ush dist = (distance); \
+ s->d_buf[s->last_lit] = dist; \
+ s->l_buf[s->last_lit++] = len; \
+ dist--; \
+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+ s->dyn_dtree[d_code(dist)].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+ flush = _tr_tally(s, distance, length)
+#endif
+
+#endif /* DEFLATE_H */
diff --git a/src/zlib/inffast.c b/src/zlib/inffast.c
new file mode 100644
index 000000000..8c02a178d
--- /dev/null
+++ b/src/zlib/inffast.c
@@ -0,0 +1,305 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifndef ASMINF
+
+/* Allow machine dependent optimization for post-increment or pre-increment.
+ Based on testing to date,
+ Pre-increment preferred for:
+ - PowerPC G3 (Adler)
+ - MIPS R5000 (Randers-Pehrson)
+ Post-increment preferred for:
+ - none
+ No measurable difference:
+ - Pentium III (Anderson)
+ - M68060 (Nikl)
+ */
+#ifdef POSTINC
+# define OFF 0
+# define PUP(a) *(a)++
+#else
+# define OFF 1
+# define PUP(a) *++(a)
+#endif
+
+/*
+ Decode literal, length, and distance codes and write out the resulting
+ literal and match bytes until either not enough input or output is
+ available, an end-of-block is encountered, or a data error is encountered.
+ When large enough input and output buffers are supplied to inflate(), for
+ example, a 16K input buffer and a 64K output buffer, more than 95% of the
+ inflate execution time is spent in this routine.
+
+ Entry assumptions:
+
+ state->mode == LEN
+ strm->avail_in >= 6
+ strm->avail_out >= 258
+ start >= strm->avail_out
+ state->bits < 8
+
+ On return, state->mode is one of:
+
+ LEN -- ran out of enough output space or enough available input
+ TYPE -- reached end of block code, inflate() to interpret next block
+ BAD -- error in block data
+
+ Notes:
+
+ - The maximum input bits used by a length/distance pair is 15 bits for the
+ length code, 5 bits for the length extra, 15 bits for the distance code,
+ and 13 bits for the distance extra. This totals 48 bits, or six bytes.
+ Therefore if strm->avail_in >= 6, then there is enough input to avoid
+ checking for available input while decoding.
+
+ - The maximum bytes that a single length/distance pair can output is 258
+ bytes, which is the maximum length that can be coded. inflate_fast()
+ requires strm->avail_out >= 258 for each loop to avoid checking for
+ output space.
+ */
+void inflate_fast(strm, start)
+z_streamp strm;
+unsigned start; /* inflate()'s starting value for strm->avail_out */
+{
+ struct inflate_state FAR *state;
+ unsigned char FAR *in; /* local strm->next_in */
+ unsigned char FAR *last; /* while in < last, enough input available */
+ unsigned char FAR *out; /* local strm->next_out */
+ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
+ unsigned char FAR *end; /* while out < end, enough space available */
+ unsigned wsize; /* window size or zero if not using window */
+ unsigned whave; /* valid bytes in the window */
+ unsigned write; /* window write index */
+ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
+ unsigned long hold; /* local strm->hold */
+ unsigned bits; /* local strm->bits */
+ code const FAR *lcode; /* local strm->lencode */
+ code const FAR *dcode; /* local strm->distcode */
+ unsigned lmask; /* mask for first level of length codes */
+ unsigned dmask; /* mask for first level of distance codes */
+ code this; /* retrieved table entry */
+ unsigned op; /* code bits, operation, extra bits, or */
+ /* window position, window bytes to copy */
+ unsigned len; /* match length, unused bytes */
+ unsigned dist; /* match distance */
+ unsigned char FAR *from; /* where to copy match from */
+
+ /* copy state to local variables */
+ state = (struct inflate_state FAR *)strm->state;
+ in = strm->next_in - OFF;
+ last = in + (strm->avail_in - 5);
+ out = strm->next_out - OFF;
+ beg = out - (start - strm->avail_out);
+ end = out + (strm->avail_out - 257);
+ wsize = state->wsize;
+ whave = state->whave;
+ write = state->write;
+ window = state->window;
+ hold = state->hold;
+ bits = state->bits;
+ lcode = state->lencode;
+ dcode = state->distcode;
+ lmask = (1U << state->lenbits) - 1;
+ dmask = (1U << state->distbits) - 1;
+
+ /* decode literals and length/distances until end-of-block or not enough
+ input data or output space */
+ do {
+ if (bits < 15) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ this = lcode[hold & lmask];
+ dolen:
+ op = (unsigned)(this.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(this.op);
+ if (op == 0) { /* literal */
+ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", this.val));
+ PUP(out) = (unsigned char)(this.val);
+ }
+ else if (op & 16) { /* length base */
+ len = (unsigned)(this.val);
+ op &= 15; /* number of extra bits */
+ if (op) {
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ len += (unsigned)hold & ((1U << op) - 1);
+ hold >>= op;
+ bits -= op;
+ }
+ Tracevv((stderr, "inflate: length %u\n", len));
+ if (bits < 15) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ this = dcode[hold & dmask];
+ dodist:
+ op = (unsigned)(this.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(this.op);
+ if (op & 16) { /* distance base */
+ dist = (unsigned)(this.val);
+ op &= 15; /* number of extra bits */
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ }
+ dist += (unsigned)hold & ((1U << op) - 1);
+ hold >>= op;
+ bits -= op;
+ Tracevv((stderr, "inflate: distance %u\n", dist));
+ op = (unsigned)(out - beg); /* max distance in output */
+ if (dist > op) { /* see if copy from window */
+ op = dist - op; /* distance back in window */
+ if (op > whave) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ from = window - OFF;
+ if (write == 0) { /* very common case */
+ from += wsize - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ else if (write < op) { /* wrap around window */
+ from += wsize + write - op;
+ op -= write;
+ if (op < len) { /* some from end of window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = window - OFF;
+ if (write < len) { /* some from start of window */
+ op = write;
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ }
+ else { /* contiguous in window */
+ from += write - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ while (len > 2) {
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ len -= 3;
+ }
+ if (len) {
+ PUP(out) = PUP(from);
+ if (len > 1)
+ PUP(out) = PUP(from);
+ }
+ }
+ else {
+ from = out - dist; /* copy direct from output */
+ do { /* minimum length is three */
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ len -= 3;
+ } while (len > 2);
+ if (len) {
+ PUP(out) = PUP(from);
+ if (len > 1)
+ PUP(out) = PUP(from);
+ }
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level distance code */
+ this = dcode[this.val + (hold & ((1U << op) - 1))];
+ goto dodist;
+ }
+ else {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level length code */
+ this = lcode[this.val + (hold & ((1U << op) - 1))];
+ goto dolen;
+ }
+ else if (op & 32) { /* end-of-block */
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+ else {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ } while (in < last && out < end);
+
+ /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+ len = bits >> 3;
+ in -= len;
+ bits -= len << 3;
+ hold &= (1U << bits) - 1;
+
+ /* update state and return */
+ strm->next_in = in + OFF;
+ strm->next_out = out + OFF;
+ strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
+ strm->avail_out = (unsigned)(out < end ?
+ 257 + (end - out) : 257 - (out - end));
+ state->hold = hold;
+ state->bits = bits;
+ return;
+}
+
+/*
+ inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
+ - Using bit fields for code structure
+ - Different op definition to avoid & for extra bits (do & for table bits)
+ - Three separate decoding do-loops for direct, window, and write == 0
+ - Special case for distance > 1 copies to do overlapped load and store copy
+ - Explicit branch predictions (based on measured branch probabilities)
+ - Deferring match copy and interspersed it with decoding subsequent codes
+ - Swapping literal/length else
+ - Swapping window/direct else
+ - Larger unrolled copy loops (three is about right)
+ - Moving len -= 3 statement into middle of loop
+ */
+
+#endif /* !ASMINF */
diff --git a/src/zlib/inffast.h b/src/zlib/inffast.h
new file mode 100644
index 000000000..1e88d2d97
--- /dev/null
+++ b/src/zlib/inffast.h
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+void inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/src/zlib/inffixed.h b/src/zlib/inffixed.h
new file mode 100644
index 000000000..75ed4b597
--- /dev/null
+++ b/src/zlib/inffixed.h
@@ -0,0 +1,94 @@
+ /* inffixed.h -- table for decoding fixed codes
+ * Generated automatically by makefixed().
+ */
+
+ /* WARNING: this file should *not* be used by applications. It
+ is part of the implementation of the compression library and
+ is subject to change. Applications should only use zlib.h.
+ */
+
+ static const code lenfix[512] = {
+ {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
+ {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
+ {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
+ {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
+ {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
+ {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
+ {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
+ {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
+ {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
+ {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
+ {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
+ {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
+ {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
+ {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
+ {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
+ {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
+ {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
+ {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+ {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
+ {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
+ {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
+ {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
+ {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
+ {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
+ {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
+ {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
+ {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
+ {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
+ {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
+ {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
+ {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
+ {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
+ {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
+ {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
+ {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
+ {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
+ {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
+ {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
+ {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
+ {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
+ {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
+ {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
+ {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
+ {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
+ {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
+ {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
+ {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
+ {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+ {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
+ {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
+ {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
+ {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
+ {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
+ {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
+ {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
+ {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
+ {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
+ {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
+ {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
+ {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
+ {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
+ {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
+ {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
+ {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
+ {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
+ {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+ {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
+ {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
+ {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
+ {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
+ {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
+ {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
+ {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
+ {0,9,255}
+ };
+
+ static const code distfix[32] = {
+ {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
+ {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
+ {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
+ {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
+ {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
+ {22,5,193},{64,5,0}
+ };
diff --git a/src/zlib/inflate.c b/src/zlib/inflate.c
new file mode 100644
index 000000000..c6d38266d
--- /dev/null
+++ b/src/zlib/inflate.c
@@ -0,0 +1,1274 @@
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * Change history:
+ *
+ * 1.2.beta0 24 Nov 2002
+ * - First version -- complete rewrite of inflate to simplify code, avoid
+ * creation of window when not needed, minimize use of window when it is
+ * needed, make inffast.c even faster, implement gzip decoding, and to
+ * improve code readability and style over the previous zlib inflate code
+ *
+ * 1.2.beta1 25 Nov 2002
+ * - Use pointers for available input and output checking in inffast.c
+ * - Remove input and output counters in inffast.c
+ * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
+ * - Remove unnecessary second byte pull from length extra in inffast.c
+ * - Unroll direct copy to three copies per loop in inffast.c
+ *
+ * 1.2.beta2 4 Dec 2002
+ * - Change external routine names to reduce potential conflicts
+ * - Correct filename to inffixed.h for fixed tables in inflate.c
+ * - Make hbuf[] unsigned char to match parameter type in inflate.c
+ * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
+ * to avoid negation problem on Alphas (64 bit) in inflate.c
+ *
+ * 1.2.beta3 22 Dec 2002
+ * - Add comments on state->bits assertion in inffast.c
+ * - Add comments on op field in inftrees.h
+ * - Fix bug in reuse of allocated window after inflateReset()
+ * - Remove bit fields--back to byte structure for speed
+ * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
+ * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
+ * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
+ * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
+ * - Use local copies of stream next and avail values, as well as local bit
+ * buffer and bit count in inflate()--for speed when inflate_fast() not used
+ *
+ * 1.2.beta4 1 Jan 2003
+ * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
+ * - Move a comment on output buffer sizes from inffast.c to inflate.c
+ * - Add comments in inffast.c to introduce the inflate_fast() routine
+ * - Rearrange window copies in inflate_fast() for speed and simplification
+ * - Unroll last copy for window match in inflate_fast()
+ * - Use local copies of window variables in inflate_fast() for speed
+ * - Pull out common write == 0 case for speed in inflate_fast()
+ * - Make op and len in inflate_fast() unsigned for consistency
+ * - Add FAR to lcode and dcode declarations in inflate_fast()
+ * - Simplified bad distance check in inflate_fast()
+ * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
+ * source file infback.c to provide a call-back interface to inflate for
+ * programs like gzip and unzip -- uses window as output buffer to avoid
+ * window copying
+ *
+ * 1.2.beta5 1 Jan 2003
+ * - Improved inflateBack() interface to allow the caller to provide initial
+ * input in strm.
+ * - Fixed stored blocks bug in inflateBack()
+ *
+ * 1.2.beta6 4 Jan 2003
+ * - Added comments in inffast.c on effectiveness of POSTINC
+ * - Typecasting all around to reduce compiler warnings
+ * - Changed loops from while (1) or do {} while (1) to for (;;), again to
+ * make compilers happy
+ * - Changed type of window in inflateBackInit() to unsigned char *
+ *
+ * 1.2.beta7 27 Jan 2003
+ * - Changed many types to unsigned or unsigned short to avoid warnings
+ * - Added inflateCopy() function
+ *
+ * 1.2.0 9 Mar 2003
+ * - Changed inflateBack() interface to provide separate opaque descriptors
+ * for the in() and out() functions
+ * - Changed inflateBack() argument and in_func typedef to swap the length
+ * and buffer address return values for the input function
+ * - Check next_in and next_out for Z_NULL on entry to inflate()
+ *
+ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef MAKEFIXED
+# ifndef BUILDFIXED
+# define BUILDFIXED
+# endif
+#endif
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+local int updatewindow OF((z_streamp strm, unsigned out));
+#ifdef BUILDFIXED
+ void makefixed OF((void));
+#endif
+local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
+ unsigned len));
+
+int ZEXPORT inflateReset(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ strm->total_in = strm->total_out = state->total = 0;
+ strm->msg = Z_NULL;
+ strm->adler = 1; /* to support ill-conceived Java test suite */
+ state->mode = HEAD;
+ state->last = 0;
+ state->havedict = 0;
+ state->wsize = 0;
+ state->whave = 0;
+ state->hold = 0;
+ state->bits = 0;
+ state->lencode = state->distcode = state->next = state->codes;
+ Tracev((stderr, "inflate: reset\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
+z_streamp strm;
+int windowBits;
+const char *version;
+int stream_size;
+{
+ struct inflate_state FAR *state;
+
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != (int)(sizeof(z_stream)))
+ return Z_VERSION_ERROR;
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+ strm->msg = Z_NULL; /* in case we return an error */
+ if (strm->zalloc == (alloc_func)0) {
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+ }
+ if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+ state = (struct inflate_state FAR *)
+ ZALLOC(strm, 1, sizeof(struct inflate_state));
+ if (state == Z_NULL) return Z_MEM_ERROR;
+ Tracev((stderr, "inflate: allocated\n"));
+ strm->state = (voidpf)state;
+ if (windowBits < 0) {
+ state->wrap = 0;
+ windowBits = -windowBits;
+ }
+ else {
+ state->wrap = (windowBits >> 4) + 1;
+#ifdef GUNZIP
+ if (windowBits < 48) windowBits &= 15;
+#endif
+ }
+ if (windowBits < 8 || windowBits > 15) {
+ ZFREE(strm, state);
+ strm->state = Z_NULL;
+ return Z_STREAM_ERROR;
+ }
+ state->wbits = (unsigned)windowBits;
+ state->window = Z_NULL;
+ return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit_(strm, version, stream_size)
+z_streamp strm;
+const char *version;
+int stream_size;
+{
+ return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+/*
+ Return state with length and distance decoding tables and index sizes set to
+ fixed code decoding. Normally this returns fixed tables from inffixed.h.
+ If BUILDFIXED is defined, then instead this routine builds the tables the
+ first time it's called, and returns those tables the first time and
+ thereafter. This reduces the size of the code by about 2K bytes, in
+ exchange for a little execution time. However, BUILDFIXED should not be
+ used for threaded applications, since the rewriting of the tables and virgin
+ may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+ static int virgin = 1;
+ static code *lenfix, *distfix;
+ static code fixed[544];
+
+ /* build fixed huffman tables if first call (may not be thread safe) */
+ if (virgin) {
+ unsigned sym, bits;
+ static code *next;
+
+ /* literal/length table */
+ sym = 0;
+ while (sym < 144) state->lens[sym++] = 8;
+ while (sym < 256) state->lens[sym++] = 9;
+ while (sym < 280) state->lens[sym++] = 7;
+ while (sym < 288) state->lens[sym++] = 8;
+ next = fixed;
+ lenfix = next;
+ bits = 9;
+ inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+ /* distance table */
+ sym = 0;
+ while (sym < 32) state->lens[sym++] = 5;
+ distfix = next;
+ bits = 5;
+ inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+ /* do this just once */
+ virgin = 0;
+ }
+#else /* !BUILDFIXED */
+# include "inffixed.h"
+#endif /* BUILDFIXED */
+ state->lencode = lenfix;
+ state->lenbits = 9;
+ state->distcode = distfix;
+ state->distbits = 5;
+}
+
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+/*
+ Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
+ defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
+ those tables to stdout, which would be piped to inffixed.h. A small program
+ can simply call makefixed to do this:
+
+ void makefixed(void);
+
+ int main(void)
+ {
+ makefixed();
+ return 0;
+ }
+
+ Then that can be linked with zlib built with MAKEFIXED defined and run:
+
+ a.out > inffixed.h
+ */
+void makefixed()
+{
+ unsigned low, size;
+ struct inflate_state state;
+
+ fixedtables(&state);
+ puts(" /* inffixed.h -- table for decoding fixed codes");
+ puts(" * Generated automatically by makefixed().");
+ puts(" */");
+ puts("");
+ puts(" /* WARNING: this file should *not* be used by applications.");
+ puts(" It is part of the implementation of this library and is");
+ puts(" subject to change. Applications should only use zlib.h.");
+ puts(" */");
+ puts("");
+ size = 1U << 9;
+ printf(" static const code lenfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 7) == 0) printf("\n ");
+ printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
+ state.lencode[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+ size = 1U << 5;
+ printf("\n static const code distfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 6) == 0) printf("\n ");
+ printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
+ state.distcode[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+}
+#endif /* MAKEFIXED */
+
+/*
+ Update the window with the last wsize (normally 32K) bytes written before
+ returning. If window does not exist yet, create it. This is only called
+ when a window is already in use, or when output has been written during this
+ inflate call, but the end of the deflate stream has not been reached yet.
+ It is also called to create a window for dictionary data when a dictionary
+ is loaded.
+
+ Providing output buffers larger than 32K to inflate() should provide a speed
+ advantage, since only the last 32K of output is copied to the sliding window
+ upon return from inflate(), and since all distances after the first 32K of
+ output will fall in the output data, making match copies simpler and faster.
+ The advantage may be dependent on the size of the processor's data caches.
+ */
+local int updatewindow(strm, out)
+z_streamp strm;
+unsigned out;
+{
+ struct inflate_state FAR *state;
+ unsigned copy, dist;
+
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* if it hasn't been done already, allocate space for the window */
+ if (state->window == Z_NULL) {
+ state->window = (unsigned char FAR *)
+ ZALLOC(strm, 1U << state->wbits,
+ sizeof(unsigned char));
+ if (state->window == Z_NULL) return 1;
+ }
+
+ /* if window not in use yet, initialize */
+ if (state->wsize == 0) {
+ state->wsize = 1U << state->wbits;
+ state->write = 0;
+ state->whave = 0;
+ }
+
+ /* copy state->wsize or less output bytes into the circular window */
+ copy = out - strm->avail_out;
+ if (copy >= state->wsize) {
+ zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
+ state->write = 0;
+ state->whave = state->wsize;
+ }
+ else {
+ dist = state->wsize - state->write;
+ if (dist > copy) dist = copy;
+ zmemcpy(state->window + state->write, strm->next_out - copy, dist);
+ copy -= dist;
+ if (copy) {
+ zmemcpy(state->window, strm->next_out - copy, copy);
+ state->write = copy;
+ state->whave = state->wsize;
+ }
+ else {
+ state->write += dist;
+ if (state->write == state->wsize) state->write = 0;
+ if (state->whave < state->wsize) state->whave += dist;
+ }
+ }
+ return 0;
+}
+
+/* Macros for inflate(): */
+
+/* check function to use adler32() for zlib or crc32() for gzip */
+#ifdef GUNZIP
+# define UPDATE(check, buf, len) \
+ (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
+#else
+# define UPDATE(check, buf, len) adler32(check, buf, len)
+#endif
+
+/* check macros for header crc */
+#ifdef GUNZIP
+# define CRC2(check, word) \
+ do { \
+ hbuf[0] = (unsigned char)(word); \
+ hbuf[1] = (unsigned char)((word) >> 8); \
+ check = crc32(check, hbuf, 2); \
+ } while (0)
+
+# define CRC4(check, word) \
+ do { \
+ hbuf[0] = (unsigned char)(word); \
+ hbuf[1] = (unsigned char)((word) >> 8); \
+ hbuf[2] = (unsigned char)((word) >> 16); \
+ hbuf[3] = (unsigned char)((word) >> 24); \
+ check = crc32(check, hbuf, 4); \
+ } while (0)
+#endif
+
+/* Load registers with state in inflate() for speed */
+#define LOAD() \
+ do { \
+ put = strm->next_out; \
+ left = strm->avail_out; \
+ next = strm->next_in; \
+ have = strm->avail_in; \
+ hold = state->hold; \
+ bits = state->bits; \
+ } while (0)
+
+/* Restore state from registers in inflate() */
+#define RESTORE() \
+ do { \
+ strm->next_out = put; \
+ strm->avail_out = left; \
+ strm->next_in = next; \
+ strm->avail_in = have; \
+ state->hold = hold; \
+ state->bits = bits; \
+ } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+ do { \
+ hold = 0; \
+ bits = 0; \
+ } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+ if there is no input available. */
+#define PULLBYTE() \
+ do { \
+ if (have == 0) goto inf_leave; \
+ have--; \
+ hold += (unsigned long)(*next++) << bits; \
+ bits += 8; \
+ } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflate(). */
+#define NEEDBITS(n) \
+ do { \
+ while (bits < (unsigned)(n)) \
+ PULLBYTE(); \
+ } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+ ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+ do { \
+ hold >>= (n); \
+ bits -= (unsigned)(n); \
+ } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+ do { \
+ hold >>= bits & 7; \
+ bits -= bits & 7; \
+ } while (0)
+
+/* Reverse the bytes in a 32-bit value */
+#define REVERSE(q) \
+ ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+/*
+ inflate() uses a state machine to process as much input data and generate as
+ much output data as possible before returning. The state machine is
+ structured roughly as follows:
+
+ for (;;) switch (state) {
+ ...
+ case STATEn:
+ if (not enough input data or output space to make progress)
+ return;
+ ... make progress ...
+ state = STATEm;
+ break;
+ ...
+ }
+
+ so when inflate() is called again, the same case is attempted again, and
+ if the appropriate resources are provided, the machine proceeds to the
+ next state. The NEEDBITS() macro is usually the way the state evaluates
+ whether it can proceed or should return. NEEDBITS() does the return if
+ the requested bits are not available. The typical use of the BITS macros
+ is:
+
+ NEEDBITS(n);
+ ... do something with BITS(n) ...
+ DROPBITS(n);
+
+ where NEEDBITS(n) either returns from inflate() if there isn't enough
+ input left to load n bits into the accumulator, or it continues. BITS(n)
+ gives the low n bits in the accumulator. When done, DROPBITS(n) drops
+ the low n bits off the accumulator. INITBITS() clears the accumulator
+ and sets the number of available bits to zero. BYTEBITS() discards just
+ enough bits to put the accumulator on a byte boundary. After BYTEBITS()
+ and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+ NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+ if there is no input available. The decoding of variable length codes uses
+ PULLBYTE() directly in order to pull just enough bytes to decode the next
+ code, and no more.
+
+ Some states loop until they get enough input, making sure that enough
+ state information is maintained to continue the loop where it left off
+ if NEEDBITS() returns in the loop. For example, want, need, and keep
+ would all have to actually be part of the saved state in case NEEDBITS()
+ returns:
+
+ case STATEw:
+ while (want < need) {
+ NEEDBITS(n);
+ keep[want++] = BITS(n);
+ DROPBITS(n);
+ }
+ state = STATEx;
+ case STATEx:
+
+ As shown above, if the next state is also the next case, then the break
+ is omitted.
+
+ A state may also return if there is not enough output space available to
+ complete that state. Those states are copying stored data, writing a
+ literal byte, and copying a matching string.
+
+ When returning, a "goto inf_leave" is used to update the total counters,
+ update the check value, and determine whether any progress has been made
+ during that inflate() call in order to return the proper return code.
+ Progress is defined as a change in either strm->avail_in or strm->avail_out.
+ When there is a window, goto inf_leave will update the window with the last
+ output written. If a goto inf_leave occurs in the middle of decompression
+ and there is no window currently, goto inf_leave will create one and copy
+ output to the window for the next call of inflate().
+
+ In this implementation, the flush parameter of inflate() only affects the
+ return code (per zlib.h). inflate() always writes as much as possible to
+ strm->next_out, given the space available and the provided input--the effect
+ documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
+ the allocation of and copying into a sliding window until necessary, which
+ provides the effect documented in zlib.h for Z_FINISH when the entire input
+ stream available. So the only thing the flush parameter actually does is:
+ when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
+ will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+
+int ZEXPORT inflate(strm, flush)
+z_streamp strm;
+int flush;
+{
+ struct inflate_state FAR *state;
+ unsigned char FAR *next; /* next input */
+ unsigned char FAR *put; /* next output */
+ unsigned have, left; /* available input and output */
+ unsigned long hold; /* bit buffer */
+ unsigned bits; /* bits in bit buffer */
+ unsigned in, out; /* save starting available input and output */
+ unsigned copy; /* number of stored or match bytes to copy */
+ unsigned char FAR *from; /* where to copy match bytes from */
+ code this; /* current decoding table entry */
+ code last; /* parent table entry */
+ unsigned len; /* length to copy for repeats, bits to drop */
+ int ret; /* return code */
+#ifdef GUNZIP
+ unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
+#endif
+ static const unsigned short order[19] = /* permutation of code lengths */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
+ (strm->next_in == Z_NULL && strm->avail_in != 0))
+ return Z_STREAM_ERROR;
+
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
+ LOAD();
+ in = have;
+ out = left;
+ ret = Z_OK;
+ for (;;)
+ switch (state->mode) {
+ case HEAD:
+ if (state->wrap == 0) {
+ state->mode = TYPEDO;
+ break;
+ }
+ NEEDBITS(16);
+#ifdef GUNZIP
+ if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
+ state->check = crc32(0L, Z_NULL, 0);
+ CRC2(state->check, hold);
+ INITBITS();
+ state->mode = FLAGS;
+ break;
+ }
+ state->flags = 0; /* expect zlib header */
+ if (!(state->wrap & 1) || /* check if zlib header allowed */
+#else
+ if (
+#endif
+ ((BITS(8) << 8) + (hold >> 8)) % 31) {
+ strm->msg = (char *)"incorrect header check";
+ state->mode = BAD;
+ break;
+ }
+ if (BITS(4) != Z_DEFLATED) {
+ strm->msg = (char *)"unknown compression method";
+ state->mode = BAD;
+ break;
+ }
+ DROPBITS(4);
+ if (BITS(4) + 8 > state->wbits) {
+ strm->msg = (char *)"invalid window size";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: zlib header ok\n"));
+ strm->adler = state->check = adler32(0L, Z_NULL, 0);
+ state->mode = hold & 0x200 ? DICTID : TYPE;
+ INITBITS();
+ break;
+#ifdef GUNZIP
+ case FLAGS:
+ NEEDBITS(16);
+ state->flags = (int)(hold);
+ if ((state->flags & 0xff) != Z_DEFLATED) {
+ strm->msg = (char *)"unknown compression method";
+ state->mode = BAD;
+ break;
+ }
+ if (state->flags & 0xe000) {
+ strm->msg = (char *)"unknown header flags set";
+ state->mode = BAD;
+ break;
+ }
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ state->mode = TIME;
+ case TIME:
+ NEEDBITS(32);
+ if (state->flags & 0x0200) CRC4(state->check, hold);
+ INITBITS();
+ state->mode = OS;
+ case OS:
+ NEEDBITS(16);
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ state->mode = EXLEN;
+ case EXLEN:
+ if (state->flags & 0x0400) {
+ NEEDBITS(16);
+ state->length = (unsigned)(hold);
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ }
+ state->mode = EXTRA;
+ case EXTRA:
+ if (state->flags & 0x0400) {
+ copy = state->length;
+ if (copy > have) copy = have;
+ if (copy) {
+ if (state->flags & 0x0200)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ state->length -= copy;
+ }
+ if (state->length) goto inf_leave;
+ }
+ state->mode = NAME;
+ case NAME:
+ if (state->flags & 0x0800) {
+ if (have == 0) goto inf_leave;
+ copy = 0;
+ do {
+ len = (unsigned)(next[copy++]);
+ } while (len && copy < have);
+ if (state->flags & 0x02000)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ if (len) goto inf_leave;
+ }
+ state->mode = COMMENT;
+ case COMMENT:
+ if (state->flags & 0x1000) {
+ if (have == 0) goto inf_leave;
+ copy = 0;
+ do {
+ len = (unsigned)(next[copy++]);
+ } while (len && copy < have);
+ if (state->flags & 0x02000)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ if (len) goto inf_leave;
+ }
+ state->mode = HCRC;
+ case HCRC:
+ if (state->flags & 0x0200) {
+ NEEDBITS(16);
+ if (hold != (state->check & 0xffff)) {
+ strm->msg = (char *)"header crc mismatch";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ }
+ strm->adler = state->check = crc32(0L, Z_NULL, 0);
+ state->mode = TYPE;
+ break;
+#endif
+ case DICTID:
+ NEEDBITS(32);
+ strm->adler = state->check = REVERSE(hold);
+ INITBITS();
+ state->mode = DICT;
+ case DICT:
+ if (state->havedict == 0) {
+ RESTORE();
+ return Z_NEED_DICT;
+ }
+ strm->adler = state->check = adler32(0L, Z_NULL, 0);
+ state->mode = TYPE;
+ case TYPE:
+ if (flush == Z_BLOCK) goto inf_leave;
+ case TYPEDO:
+ if (state->last) {
+ BYTEBITS();
+ state->mode = CHECK;
+ break;
+ }
+ NEEDBITS(3);
+ state->last = BITS(1);
+ DROPBITS(1);
+ switch (BITS(2)) {
+ case 0: /* stored block */
+ Tracev((stderr, "inflate: stored block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = STORED;
+ break;
+ case 1: /* fixed block */
+ fixedtables(state);
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = LEN; /* decode codes */
+ break;
+ case 2: /* dynamic block */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = TABLE;
+ break;
+ case 3:
+ strm->msg = (char *)"invalid block type";
+ state->mode = BAD;
+ }
+ DROPBITS(2);
+ break;
+ case STORED:
+ BYTEBITS(); /* go to byte boundary */
+ NEEDBITS(32);
+ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+ strm->msg = (char *)"invalid stored block lengths";
+ state->mode = BAD;
+ break;
+ }
+ state->length = (unsigned)hold & 0xffff;
+ Tracev((stderr, "inflate: stored length %u\n",
+ state->length));
+ INITBITS();
+ state->mode = COPY;
+ case COPY:
+ copy = state->length;
+ if (copy) {
+ if (copy > have) copy = have;
+ if (copy > left) copy = left;
+ if (copy == 0) goto inf_leave;
+ zmemcpy(put, next, copy);
+ have -= copy;
+ next += copy;
+ left -= copy;
+ put += copy;
+ state->length -= copy;
+ break;
+ }
+ Tracev((stderr, "inflate: stored end\n"));
+ state->mode = TYPE;
+ break;
+ case TABLE:
+ NEEDBITS(14);
+ state->nlen = BITS(5) + 257;
+ DROPBITS(5);
+ state->ndist = BITS(5) + 1;
+ DROPBITS(5);
+ state->ncode = BITS(4) + 4;
+ DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+ if (state->nlen > 286 || state->ndist > 30) {
+ strm->msg = (char *)"too many length or distance symbols";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracev((stderr, "inflate: table sizes ok\n"));
+ state->have = 0;
+ state->mode = LENLENS;
+ case LENLENS:
+ while (state->have < state->ncode) {
+ NEEDBITS(3);
+ state->lens[order[state->have++]] = (unsigned short)BITS(3);
+ DROPBITS(3);
+ }
+ while (state->have < 19)
+ state->lens[order[state->have++]] = 0;
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 7;
+ ret = inflate_table(CODES, state->lens, 19, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid code lengths set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: code lengths ok\n"));
+ state->have = 0;
+ state->mode = CODELENS;
+ case CODELENS:
+ while (state->have < state->nlen + state->ndist) {
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.val < 16) {
+ NEEDBITS(this.bits);
+ DROPBITS(this.bits);
+ state->lens[state->have++] = this.val;
+ }
+ else {
+ if (this.val == 16) {
+ NEEDBITS(this.bits + 2);
+ DROPBITS(this.bits);
+ if (state->have == 0) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ len = state->lens[state->have - 1];
+ copy = 3 + BITS(2);
+ DROPBITS(2);
+ }
+ else if (this.val == 17) {
+ NEEDBITS(this.bits + 3);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 3 + BITS(3);
+ DROPBITS(3);
+ }
+ else {
+ NEEDBITS(this.bits + 7);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 11 + BITS(7);
+ DROPBITS(7);
+ }
+ if (state->have + copy > state->nlen + state->ndist) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ while (copy--)
+ state->lens[state->have++] = (unsigned short)len;
+ }
+ }
+
+ /* handle error breaks in while */
+ if (state->mode == BAD) break;
+
+ /* build code tables */
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 9;
+ ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid literal/lengths set";
+ state->mode = BAD;
+ break;
+ }
+ state->distcode = (code const FAR *)(state->next);
+ state->distbits = 6;
+ ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+ &(state->next), &(state->distbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid distances set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: codes ok\n"));
+ state->mode = LEN;
+ case LEN:
+ if (have >= 6 && left >= 258) {
+ RESTORE();
+ inflate_fast(strm, out);
+ LOAD();
+ break;
+ }
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.op && (this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ state->length = (unsigned)this.val;
+ if ((int)(this.op) == 0) {
+ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", this.val));
+ state->mode = LIT;
+ break;
+ }
+ if (this.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ state->extra = (unsigned)(this.op) & 15;
+ state->mode = LENEXT;
+ case LENEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->length += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ Tracevv((stderr, "inflate: length %u\n", state->length));
+ state->mode = DIST;
+ case DIST:
+ for (;;) {
+ this = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if ((this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->distcode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ state->offset = (unsigned)this.val;
+ state->extra = (unsigned)(this.op) & 15;
+ state->mode = DISTEXT;
+ case DISTEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->offset += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ if (state->offset > state->whave + out - left) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ Tracevv((stderr, "inflate: distance %u\n", state->offset));
+ state->mode = MATCH;
+ case MATCH:
+ if (left == 0) goto inf_leave;
+ copy = out - left;
+ if (state->offset > copy) { /* copy from window */
+ copy = state->offset - copy;
+ if (copy > state->write) {
+ copy -= state->write;
+ from = state->window + (state->wsize - copy);
+ }
+ else
+ from = state->window + (state->write - copy);
+ if (copy > state->length) copy = state->length;
+ }
+ else { /* copy from output */
+ from = put - state->offset;
+ copy = state->length;
+ }
+ if (copy > left) copy = left;
+ left -= copy;
+ state->length -= copy;
+ do {
+ *put++ = *from++;
+ } while (--copy);
+ if (state->length == 0) state->mode = LEN;
+ break;
+ case LIT:
+ if (left == 0) goto inf_leave;
+ *put++ = (unsigned char)(state->length);
+ left--;
+ state->mode = LEN;
+ break;
+ case CHECK:
+ if (state->wrap) {
+ NEEDBITS(32);
+ out -= left;
+ strm->total_out += out;
+ state->total += out;
+ if (out)
+ strm->adler = state->check =
+ UPDATE(state->check, put - out, out);
+ out = left;
+ if ((
+#ifdef GUNZIP
+ state->flags ? hold :
+#endif
+ REVERSE(hold)) != state->check) {
+ strm->msg = (char *)"incorrect data check";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ Tracev((stderr, "inflate: check matches trailer\n"));
+ }
+#ifdef GUNZIP
+ state->mode = LENGTH;
+ case LENGTH:
+ if (state->wrap && state->flags) {
+ NEEDBITS(32);
+ if (hold != (state->total & 0xffffffffUL)) {
+ strm->msg = (char *)"incorrect length check";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ Tracev((stderr, "inflate: length matches trailer\n"));
+ }
+#endif
+ state->mode = DONE;
+ case DONE:
+ ret = Z_STREAM_END;
+ goto inf_leave;
+ case BAD:
+ ret = Z_DATA_ERROR;
+ goto inf_leave;
+ case MEM:
+ return Z_MEM_ERROR;
+ case SYNC:
+ default:
+ return Z_STREAM_ERROR;
+ }
+
+ /*
+ Return from inflate(), updating the total counts and the check value.
+ If there was no progress during the inflate() call, return a buffer
+ error. Call updatewindow() to create and/or update the window state.
+ Note: a memory error from inflate() is non-recoverable.
+ */
+ inf_leave:
+ RESTORE();
+ if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
+ if (updatewindow(strm, out)) {
+ state->mode = MEM;
+ return Z_MEM_ERROR;
+ }
+ in -= strm->avail_in;
+ out -= strm->avail_out;
+ strm->total_in += in;
+ strm->total_out += out;
+ state->total += out;
+ if (state->wrap && out)
+ strm->adler = state->check =
+ UPDATE(state->check, strm->next_out - out, out);
+ strm->data_type = state->bits + (state->last ? 64 : 0) +
+ (state->mode == TYPE ? 128 : 0);
+ if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+ ret = Z_BUF_ERROR;
+ return ret;
+}
+
+int ZEXPORT inflateEnd(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->window != Z_NULL) ZFREE(strm, state->window);
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+const Bytef *dictionary;
+uInt dictLength;
+{
+ struct inflate_state FAR *state;
+ unsigned long id;
+
+ /* check state */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->mode != DICT) return Z_STREAM_ERROR;
+
+ /* check for correct dictionary id */
+ id = adler32(0L, Z_NULL, 0);
+ id = adler32(id, dictionary, dictLength);
+ if (id != state->check) return Z_DATA_ERROR;
+
+ /* copy dictionary to window */
+ if (updatewindow(strm, strm->avail_out)) {
+ state->mode = MEM;
+ return Z_MEM_ERROR;
+ }
+ if (dictLength > state->wsize) {
+ zmemcpy(state->window, dictionary + dictLength - state->wsize,
+ state->wsize);
+ state->whave = state->wsize;
+ }
+ else {
+ zmemcpy(state->window + state->wsize - dictLength, dictionary,
+ dictLength);
+ state->whave = dictLength;
+ }
+ state->havedict = 1;
+ Tracev((stderr, "inflate: dictionary set\n"));
+ return Z_OK;
+}
+
+/*
+ Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
+ or when out of input. When called, *have is the number of pattern bytes
+ found in order so far, in 0..3. On return *have is updated to the new
+ state. If on return *have equals four, then the pattern was found and the
+ return value is how many bytes were read including the last byte of the
+ pattern. If *have is less than four, then the pattern has not been found
+ yet and the return value is len. In the latter case, syncsearch() can be
+ called again with more data and the *have state. *have is initialized to
+ zero for the first call.
+ */
+local unsigned syncsearch(have, buf, len)
+unsigned FAR *have;
+unsigned char FAR *buf;
+unsigned len;
+{
+ unsigned got;
+ unsigned next;
+
+ got = *have;
+ next = 0;
+ while (next < len && got < 4) {
+ if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
+ got++;
+ else if (buf[next])
+ got = 0;
+ else
+ got = 4 - got;
+ next++;
+ }
+ *have = got;
+ return next;
+}
+
+int ZEXPORT inflateSync(strm)
+z_streamp strm;
+{
+ unsigned len; /* number of bytes to look at or looked at */
+ unsigned long in, out; /* temporary to save total_in and total_out */
+ unsigned char buf[4]; /* to restore bit buffer to byte string */
+ struct inflate_state FAR *state;
+
+ /* check parameters */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
+
+ /* if first time, start search in bit buffer */
+ if (state->mode != SYNC) {
+ state->mode = SYNC;
+ state->hold <<= state->bits & 7;
+ state->bits -= state->bits & 7;
+ len = 0;
+ while (state->bits >= 8) {
+ buf[len++] = (unsigned char)(state->hold);
+ state->hold >>= 8;
+ state->bits -= 8;
+ }
+ state->have = 0;
+ syncsearch(&(state->have), buf, len);
+ }
+
+ /* search available input */
+ len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
+ strm->avail_in -= len;
+ strm->next_in += len;
+ strm->total_in += len;
+
+ /* return no joy or set up to restart inflate() on a new block */
+ if (state->have != 4) return Z_DATA_ERROR;
+ in = strm->total_in; out = strm->total_out;
+ inflateReset(strm);
+ strm->total_in = in; strm->total_out = out;
+ state->mode = TYPE;
+ return Z_OK;
+}
+
+/*
+ Returns true if inflate is currently at the end of a block generated by
+ Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ implementation to provide an additional safety check. PPP uses
+ Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
+ block. When decompressing, PPP checks that at the end of input packet,
+ inflate is waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ return state->mode == STORED && state->bits == 0;
+}
+
+int ZEXPORT inflateCopy(dest, source)
+z_streamp dest;
+z_streamp source;
+{
+ struct inflate_state FAR *state;
+ struct inflate_state FAR *copy;
+ unsigned char FAR *window;
+
+ /* check input */
+ if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
+ source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)source->state;
+
+ /* allocate space */
+ copy = (struct inflate_state FAR *)
+ ZALLOC(source, 1, sizeof(struct inflate_state));
+ if (copy == Z_NULL) return Z_MEM_ERROR;
+ window = Z_NULL;
+ if (state->window != Z_NULL) {
+ window = (unsigned char FAR *)
+ ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
+ if (window == Z_NULL) {
+ ZFREE(source, copy);
+ return Z_MEM_ERROR;
+ }
+ }
+
+ /* copy state */
+ *dest = *source;
+ *copy = *state;
+ copy->lencode = copy->codes + (state->lencode - state->codes);
+ copy->distcode = copy->codes + (state->distcode - state->codes);
+ copy->next = copy->codes + (state->next - state->codes);
+ if (window != Z_NULL)
+ zmemcpy(window, state->window, 1U << state->wbits);
+ copy->window = window;
+ dest->state = (voidpf)copy;
+ return Z_OK;
+}
diff --git a/src/zlib/inflate.h b/src/zlib/inflate.h
new file mode 100644
index 000000000..9a12c8fd2
--- /dev/null
+++ b/src/zlib/inflate.h
@@ -0,0 +1,117 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+ trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
+ the crc code when it is not needed. For shared libraries, gzip decoding
+ should be left enabled. */
+#ifndef NO_GZIP
+# define GUNZIP
+#endif
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+ HEAD, /* i: waiting for magic header */
+#ifdef GUNZIP
+ FLAGS, /* i: waiting for method and flags (gzip) */
+ TIME, /* i: waiting for modification time (gzip) */
+ OS, /* i: waiting for extra flags and operating system (gzip) */
+ EXLEN, /* i: waiting for extra length (gzip) */
+ EXTRA, /* i: waiting for extra bytes (gzip) */
+ NAME, /* i: waiting for end of file name (gzip) */
+ COMMENT, /* i: waiting for end of comment (gzip) */
+ HCRC, /* i: waiting for header crc (gzip) */
+#endif
+ DICTID, /* i: waiting for dictionary check value */
+ DICT, /* waiting for inflateSetDictionary() call */
+ TYPE, /* i: waiting for type bits, including last-flag bit */
+ TYPEDO, /* i: same, but skip check to exit inflate on new block */
+ STORED, /* i: waiting for stored size (length and complement) */
+ COPY, /* i/o: waiting for input or output to copy stored block */
+ TABLE, /* i: waiting for dynamic block table lengths */
+ LENLENS, /* i: waiting for code length code lengths */
+ CODELENS, /* i: waiting for length/lit and distance code lengths */
+ LEN, /* i: waiting for length/lit code */
+ LENEXT, /* i: waiting for length extra bits */
+ DIST, /* i: waiting for distance code */
+ DISTEXT, /* i: waiting for distance extra bits */
+ MATCH, /* o: waiting for output space to copy string */
+ LIT, /* o: waiting for output space to write literal */
+ CHECK, /* i: waiting for 32-bit check value */
+#ifdef GUNZIP
+ LENGTH, /* i: waiting for 32-bit length (gzip) */
+#endif
+ DONE, /* finished check, done -- remain here until reset */
+ BAD, /* got a data error -- remain here until reset */
+ MEM, /* got an inflate() memory error -- remain here until reset */
+ SYNC /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+ State transitions between above modes -
+
+ (most modes can go to the BAD or MEM mode -- not shown for clarity)
+
+ Process header:
+ HEAD -> (gzip) or (zlib)
+ (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
+ NAME -> COMMENT -> HCRC -> TYPE
+ (zlib) -> DICTID or TYPE
+ DICTID -> DICT -> TYPE
+ Read deflate blocks:
+ TYPE -> STORED or TABLE or LEN or CHECK
+ STORED -> COPY -> TYPE
+ TABLE -> LENLENS -> CODELENS -> LEN
+ Read deflate codes:
+ LEN -> LENEXT or LIT or TYPE
+ LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+ LIT -> LEN
+ Process trailer:
+ CHECK -> LENGTH -> DONE
+ */
+
+/* state maintained between inflate() calls. Approximately 7K bytes. */
+struct inflate_state {
+ inflate_mode mode; /* current inflate mode */
+ int last; /* true if processing last block */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
+ int havedict; /* true if dictionary provided */
+ int flags; /* gzip header method and flags (0 if zlib) */
+ unsigned long check; /* protected copy of check value */
+ unsigned long total; /* protected copy of output count */
+ /* sliding window */
+ unsigned wbits; /* log base 2 of requested window size */
+ unsigned wsize; /* window size or zero if not using window */
+ unsigned whave; /* valid bytes in the window */
+ unsigned write; /* window write index */
+ unsigned char FAR *window; /* allocated sliding window, if needed */
+ /* bit accumulator */
+ unsigned long hold; /* input bit accumulator */
+ unsigned bits; /* number of bits in "in" */
+ /* for string and stored block copying */
+ unsigned length; /* literal or length of data to copy */
+ unsigned offset; /* distance back to copy string from */
+ /* for table and code decoding */
+ unsigned extra; /* extra bits needed */
+ /* fixed and dynamic code tables */
+ code const FAR *lencode; /* starting table for length/literal codes */
+ code const FAR *distcode; /* starting table for distance codes */
+ unsigned lenbits; /* index bits for lencode */
+ unsigned distbits; /* index bits for distcode */
+ /* dynamic table building */
+ unsigned ncode; /* number of code length code lengths */
+ unsigned nlen; /* number of length code lengths */
+ unsigned ndist; /* number of distance code lengths */
+ unsigned have; /* number of code lengths in lens[] */
+ code FAR *next; /* next available space in codes[] */
+ unsigned short lens[320]; /* temporary storage for code lengths */
+ unsigned short work[288]; /* work area for code table building */
+ code codes[ENOUGH]; /* space for code tables */
+};
diff --git a/src/zlib/inftrees.c b/src/zlib/inftrees.c
new file mode 100644
index 000000000..8a896b287
--- /dev/null
+++ b/src/zlib/inftrees.c
@@ -0,0 +1,328 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#define MAXBITS 15
+
+const char inflate_copyright[] =
+ " inflate 1.2.2 Copyright 1995-2004 Mark Adler ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/*
+ Build a set of tables to decode the provided canonical Huffman code.
+ The code lengths are lens[0..codes-1]. The result starts at *table,
+ whose indices are 0..2^bits-1. work is a writable array of at least
+ lens shorts, which is used as a work area. type is the type of code
+ to be generated, CODES, LENS, or DISTS. On return, zero is success,
+ -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
+ on return points to the next available entry's address. bits is the
+ requested root table index bits, and on return it is the actual root
+ table index bits. It will differ if the request is greater than the
+ longest code or if it is less than the shortest code.
+ */
+int inflate_table(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+ unsigned len; /* a code's length in bits */
+ unsigned sym; /* index of code symbols */
+ unsigned min, max; /* minimum and maximum code lengths */
+ unsigned root; /* number of index bits for root table */
+ unsigned curr; /* number of index bits for current table */
+ unsigned drop; /* code bits to drop for sub-table */
+ int left; /* number of prefix codes available */
+ unsigned used; /* code entries in table used */
+ unsigned huff; /* Huffman code */
+ unsigned incr; /* for incrementing code, index */
+ unsigned fill; /* index for replicating entries */
+ unsigned low; /* low bits for current root entry */
+ unsigned mask; /* mask for low root bits */
+ code this; /* table entry for duplication */
+ code FAR *next; /* next available space in table */
+ const unsigned short FAR *base; /* base value table to use */
+ const unsigned short FAR *extra; /* extra bits table to use */
+ int end; /* use base and extra for symbol > end */
+ unsigned short count[MAXBITS+1]; /* number of codes of each length */
+ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
+ static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+ static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+ 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 199, 198};
+ static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+ 8193, 12289, 16385, 24577, 0, 0};
+ static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
+ 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+ 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+ 28, 28, 29, 29, 64, 64};
+
+ /*
+ Process a set of code lengths to create a canonical Huffman code. The
+ code lengths are lens[0..codes-1]. Each length corresponds to the
+ symbols 0..codes-1. The Huffman code is generated by first sorting the
+ symbols by length from short to long, and retaining the symbol order
+ for codes with equal lengths. Then the code starts with all zero bits
+ for the first code of the shortest length, and the codes are integer
+ increments for the same length, and zeros are appended as the length
+ increases. For the deflate format, these bits are stored backwards
+ from their more natural integer increment ordering, and so when the
+ decoding tables are built in the large loop below, the integer codes
+ are incremented backwards.
+
+ This routine assumes, but does not check, that all of the entries in
+ lens[] are in the range 0..MAXBITS. The caller must assure this.
+ 1..MAXBITS is interpreted as that code length. zero means that that
+ symbol does not occur in this code.
+
+ The codes are sorted by computing a count of codes for each length,
+ creating from that a table of starting indices for each length in the
+ sorted table, and then entering the symbols in order in the sorted
+ table. The sorted table is work[], with that space being provided by
+ the caller.
+
+ The length counts are used for other purposes as well, i.e. finding
+ the minimum and maximum length codes, determining if there are any
+ codes at all, checking for a valid set of lengths, and looking ahead
+ at length counts to determine sub-table sizes when building the
+ decoding tables.
+ */
+
+ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+ for (len = 0; len <= MAXBITS; len++)
+ count[len] = 0;
+ for (sym = 0; sym < codes; sym++)
+ count[lens[sym]]++;
+
+ /* bound code lengths, force root to be within code lengths */
+ root = *bits;
+ for (max = MAXBITS; max >= 1; max--)
+ if (count[max] != 0) break;
+ if (root > max) root = max;
+ if (max == 0) { /* no symbols to code at all */
+ this.op = (unsigned char)64; /* invalid code marker */
+ this.bits = (unsigned char)1;
+ this.val = (unsigned short)0;
+ *(*table)++ = this; /* make a table to force an error */
+ *(*table)++ = this;
+ *bits = 1;
+ return 0; /* no symbols, but wait for decoding to report error */
+ }
+ for (min = 1; min <= MAXBITS; min++)
+ if (count[min] != 0) break;
+ if (root < min) root = min;
+
+ /* check for an over-subscribed or incomplete set of lengths */
+ left = 1;
+ for (len = 1; len <= MAXBITS; len++) {
+ left <<= 1;
+ left -= count[len];
+ if (left < 0) return -1; /* over-subscribed */
+ }
+ if (left > 0 && (type == CODES || (codes - count[0] != 1)))
+ return -1; /* incomplete set */
+
+ /* generate offsets into symbol table for each length for sorting */
+ offs[1] = 0;
+ for (len = 1; len < MAXBITS; len++)
+ offs[len + 1] = offs[len] + count[len];
+
+ /* sort symbols by length, by symbol order within each length */
+ for (sym = 0; sym < codes; sym++)
+ if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+ /*
+ Create and fill in decoding tables. In this loop, the table being
+ filled is at next and has curr index bits. The code being used is huff
+ with length len. That code is converted to an index by dropping drop
+ bits off of the bottom. For codes where len is less than drop + curr,
+ those top drop + curr - len bits are incremented through all values to
+ fill the table with replicated entries.
+
+ root is the number of index bits for the root table. When len exceeds
+ root, sub-tables are created pointed to by the root entry with an index
+ of the low root bits of huff. This is saved in low to check for when a
+ new sub-table should be started. drop is zero when the root table is
+ being filled, and drop is root when sub-tables are being filled.
+
+ When a new sub-table is needed, it is necessary to look ahead in the
+ code lengths to determine what size sub-table is needed. The length
+ counts are used for this, and so count[] is decremented as codes are
+ entered in the tables.
+
+ used keeps track of how many table entries have been allocated from the
+ provided *table space. It is checked when a LENS table is being made
+ against the space in *table, ENOUGH, minus the maximum space needed by
+ the worst case distance code, MAXD. This should never happen, but the
+ sufficiency of ENOUGH has not been proven exhaustively, hence the check.
+ This assumes that when type == LENS, bits == 9.
+
+ sym increments through all symbols, and the loop terminates when
+ all codes of length max, i.e. all codes, have been processed. This
+ routine permits incomplete codes, so another loop after this one fills
+ in the rest of the decoding tables with invalid code markers.
+ */
+
+ /* set up for code type */
+ switch (type) {
+ case CODES:
+ base = extra = work; /* dummy value--not used */
+ end = 19;
+ break;
+ case LENS:
+ base = lbase;
+ base -= 257;
+ extra = lext;
+ extra -= 257;
+ end = 256;
+ break;
+ default: /* DISTS */
+ base = dbase;
+ extra = dext;
+ end = -1;
+ }
+
+ /* initialize state for loop */
+ huff = 0; /* starting code */
+ sym = 0; /* starting code symbol */
+ len = min; /* starting code length */
+ next = *table; /* current table to fill in */
+ curr = root; /* current table index bits */
+ drop = 0; /* current bits to drop from code for index */
+ low = (unsigned)(-1); /* trigger new sub-table when len > root */
+ used = 1U << root; /* use root table entries */
+ mask = used - 1; /* mask for comparing low */
+
+ /* check available table space */
+ if (type == LENS && used >= ENOUGH - MAXD)
+ return 1;
+
+ /* process all codes and make table entries */
+ for (;;) {
+ /* create table entry */
+ this.bits = (unsigned char)(len - drop);
+ if ((int)(work[sym]) < end) {
+ this.op = (unsigned char)0;
+ this.val = work[sym];
+ }
+ else if ((int)(work[sym]) > end) {
+ this.op = (unsigned char)(extra[work[sym]]);
+ this.val = base[work[sym]];
+ }
+ else {
+ this.op = (unsigned char)(32 + 64); /* end of block */
+ this.val = 0;
+ }
+
+ /* replicate for those indices with low len bits equal to huff */
+ incr = 1U << (len - drop);
+ fill = 1U << curr;
+ do {
+ fill -= incr;
+ next[(huff >> drop) + fill] = this;
+ } while (fill != 0);
+
+ /* backwards increment the len-bit code huff */
+ incr = 1U << (len - 1);
+ while (huff & incr)
+ incr >>= 1;
+ if (incr != 0) {
+ huff &= incr - 1;
+ huff += incr;
+ }
+ else
+ huff = 0;
+
+ /* go to next symbol, update count, len */
+ sym++;
+ if (--(count[len]) == 0) {
+ if (len == max) break;
+ len = lens[work[sym]];
+ }
+
+ /* create new sub-table if needed */
+ if (len > root && (huff & mask) != low) {
+ /* if first time, transition to sub-tables */
+ if (drop == 0)
+ drop = root;
+
+ /* increment past last table */
+ next += 1U << curr;
+
+ /* determine length of next table */
+ curr = len - drop;
+ left = (int)(1 << curr);
+ while (curr + drop < max) {
+ left -= count[curr + drop];
+ if (left <= 0) break;
+ curr++;
+ left <<= 1;
+ }
+
+ /* check for enough space */
+ used += 1U << curr;
+ if (type == LENS && used >= ENOUGH - MAXD)
+ return 1;
+
+ /* point entry in root table to sub-table */
+ low = huff & mask;
+ (*table)[low].op = (unsigned char)curr;
+ (*table)[low].bits = (unsigned char)root;
+ (*table)[low].val = (unsigned short)(next - *table);
+ }
+ }
+
+ /*
+ Fill in rest of table for incomplete codes. This loop is similar to the
+ loop above in incrementing huff for table indices. It is assumed that
+ len is equal to curr + drop, so there is no loop needed to increment
+ through high index bits. When the current sub-table is filled, the loop
+ drops back to the root table to fill in any remaining entries there.
+ */
+ this.op = (unsigned char)64; /* invalid code marker */
+ this.bits = (unsigned char)(len - drop);
+ this.val = (unsigned short)0;
+ while (huff != 0) {
+ /* when done with sub-table, drop back to root table */
+ if (drop != 0 && (huff & mask) != low) {
+ drop = 0;
+ len = root;
+ next = *table;
+ this.bits = (unsigned char)len;
+ }
+
+ /* put invalid code marker in table */
+ next[huff >> drop] = this;
+
+ /* backwards increment the len-bit code huff */
+ incr = 1U << (len - 1);
+ while (huff & incr)
+ incr >>= 1;
+ if (incr != 0) {
+ huff &= incr - 1;
+ huff += incr;
+ }
+ else
+ huff = 0;
+ }
+
+ /* set return parameters */
+ *table += used;
+ *bits = root;
+ return 0;
+}
diff --git a/src/zlib/inftrees.h b/src/zlib/inftrees.h
new file mode 100644
index 000000000..82d365a7e
--- /dev/null
+++ b/src/zlib/inftrees.h
@@ -0,0 +1,55 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables. Each entry provides either the
+ information needed to do the operation requested by the code that
+ indexed that table entry, or it provides a pointer to another
+ table that indexes more bits of the code. op indicates whether
+ the entry is a pointer to another table, a literal, a length or
+ distance, an end-of-block, or an invalid code. For a table
+ pointer, the low four bits of op is the number of index bits of
+ that table. For a length or distance, the low four bits of op
+ is the number of extra bits to get after the code. bits is
+ the number of bits in this code or part of the code to drop off
+ of the bit buffer. val is the actual byte to output in the case
+ of a literal, the base length or distance, or the offset from
+ the current table to the next table. Each entry is four bytes. */
+typedef struct {
+ unsigned char op; /* operation, extra bits, table bits */
+ unsigned char bits; /* bits in this part of the code */
+ unsigned short val; /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+ 00000000 - literal
+ 0000tttt - table link, tttt != 0 is the number of table index bits
+ 0001eeee - length or distance, eeee is the number of extra bits
+ 01100000 - end of block
+ 01000000 - invalid code
+ */
+
+/* Maximum size of dynamic tree. The maximum found in a long but non-
+ exhaustive search was 1004 code structures (850 for length/literals
+ and 154 for distances, the latter actually the result of an
+ exhaustive search). The true maximum is not known, but the value
+ below is more than safe. */
+#define ENOUGH 1440
+#define MAXD 154
+
+/* Type of code to build for inftable() */
+typedef enum {
+ CODES,
+ LENS,
+ DISTS
+} codetype;
+
+extern int inflate_table OF((codetype type, unsigned short FAR *lens,
+ unsigned codes, code FAR * FAR *table,
+ unsigned FAR *bits, unsigned short FAR *work));
diff --git a/src/zlib/trees.c b/src/zlib/trees.c
new file mode 100644
index 000000000..52c820fa2
--- /dev/null
+++ b/src/zlib/trees.c
@@ -0,0 +1,1215 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2003 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process uses several Huffman trees. The more
+ * common source values are represented by shorter bit sequences.
+ *
+ * Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values). The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ * Storer, James A.
+ * Data Compression: Methods and Theory, pp. 49-50.
+ * Computer Science Press, 1988. ISBN 0-7167-8156-5.
+ *
+ * Sedgewick, R.
+ * Algorithms, p290.
+ * Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id$ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef DEBUG
+# include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6 16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10 17
+/* repeat a zero length 3-10 times (3 bits of repeat count) */
+
+#define REPZ_11_138 18
+/* repeat a zero length 11-138 times (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+#define Buf_size (8 * 2*sizeof(char))
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
+ * more than 16 bits on some systems.)
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+# include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+ const ct_data *static_tree; /* static tree or NULL */
+ const intf *extra_bits; /* extra bits for each code or NULL */
+ int extra_base; /* base index for extra_bits */
+ int elems; /* max number of elements in the tree */
+ int max_length; /* max bit length for the codes */
+};
+
+local static_tree_desc static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc static_d_desc =
+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
+
+local static_tree_desc static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block OF((deflate_state *s));
+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree OF((deflate_state *s, tree_desc *desc));
+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local int build_bl_tree OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+ int blcodes));
+local void compress_block OF((deflate_state *s, ct_data *ltree,
+ ct_data *dtree));
+local void set_data_type OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup OF((deflate_state *s));
+local void bi_flush OF((deflate_state *s));
+local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
+ int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG
+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+ /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+# define send_code(s, c, tree) \
+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+ send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+ put_byte(s, (uch)((w) & 0xff)); \
+ put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG
+local void send_bits OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+ deflate_state *s;
+ int value; /* value to send */
+ int length; /* number of bits */
+{
+ Tracevv((stderr," l %2d v %4x ", length, value));
+ Assert(length > 0 && length <= 15, "invalid length");
+ s->bits_sent += (ulg)length;
+
+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+ * unused bits in value.
+ */
+ if (s->bi_valid > (int)Buf_size - length) {
+ s->bi_buf |= (value << s->bi_valid);
+ put_short(s, s->bi_buf);
+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+ s->bi_valid += length - Buf_size;
+ } else {
+ s->bi_buf |= value << s->bi_valid;
+ s->bi_valid += length;
+ }
+}
+#else /* !DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+ if (s->bi_valid > (int)Buf_size - len) {\
+ int val = value;\
+ s->bi_buf |= (val << s->bi_valid);\
+ put_short(s, s->bi_buf);\
+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+ s->bi_valid += len - Buf_size;\
+ } else {\
+ s->bi_buf |= (value) << s->bi_valid;\
+ s->bi_valid += len;\
+ }\
+}
+#endif /* DEBUG */
+
+
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+ static int static_init_done = 0;
+ int n; /* iterates over tree elements */
+ int bits; /* bit counter */
+ int length; /* length value */
+ int code; /* code value */
+ int dist; /* distance index */
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ if (static_init_done) return;
+
+ /* For some embedded targets, global variables are not initialized: */
+ static_l_desc.static_tree = static_ltree;
+ static_l_desc.extra_bits = extra_lbits;
+ static_d_desc.static_tree = static_dtree;
+ static_d_desc.extra_bits = extra_dbits;
+ static_bl_desc.extra_bits = extra_blbits;
+
+ /* Initialize the mapping length (0..255) -> length code (0..28) */
+ length = 0;
+ for (code = 0; code < LENGTH_CODES-1; code++) {
+ base_length[code] = length;
+ for (n = 0; n < (1<<extra_lbits[code]); n++) {
+ _length_code[length++] = (uch)code;
+ }
+ }
+ Assert (length == 256, "tr_static_init: length != 256");
+ /* Note that the length 255 (match length 258) can be represented
+ * in two different ways: code 284 + 5 bits or code 285, so we
+ * overwrite length_code[255] to use the best encoding:
+ */
+ _length_code[length-1] = (uch)code;
+
+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+ dist = 0;
+ for (code = 0 ; code < 16; code++) {
+ base_dist[code] = dist;
+ for (n = 0; n < (1<<extra_dbits[code]); n++) {
+ _dist_code[dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: dist != 256");
+ dist >>= 7; /* from now on, all distances are divided by 128 */
+ for ( ; code < D_CODES; code++) {
+ base_dist[code] = dist << 7;
+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+ _dist_code[256 + dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+ /* Construct the codes of the static literal tree */
+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+ n = 0;
+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+ /* Codes 286 and 287 do not exist, but we must include them in the
+ * tree construction to get a canonical Huffman tree (longest code
+ * all ones)
+ */
+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+ /* The static distance tree is trivial: */
+ for (n = 0; n < D_CODES; n++) {
+ static_dtree[n].Len = 5;
+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+ }
+ static_init_done = 1;
+
+# ifdef GEN_TREES_H
+ gen_trees_header();
+# endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+# ifndef DEBUG
+# include <stdio.h>
+# endif
+
+# define SEPARATOR(i, last, width) \
+ ((i) == (last)? "\n};\n\n" : \
+ ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+ FILE *header = fopen("trees.h", "w");
+ int i;
+
+ Assert (header != NULL, "Can't open trees.h");
+ fprintf(header,
+ "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+ for (i = 0; i < L_CODES+2; i++) {
+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+ }
+
+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+ }
+
+ fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
+ for (i = 0; i < DIST_CODE_LEN; i++) {
+ fprintf(header, "%2u%s", _dist_code[i],
+ SEPARATOR(i, DIST_CODE_LEN-1, 20));
+ }
+
+ fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+ fprintf(header, "%2u%s", _length_code[i],
+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+ }
+
+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+ for (i = 0; i < LENGTH_CODES; i++) {
+ fprintf(header, "%1u%s", base_length[i],
+ SEPARATOR(i, LENGTH_CODES-1, 20));
+ }
+
+ fprintf(header, "local const int base_dist[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "%5u%s", base_dist[i],
+ SEPARATOR(i, D_CODES-1, 10));
+ }
+
+ fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void _tr_init(s)
+ deflate_state *s;
+{
+ tr_static_init();
+
+ s->l_desc.dyn_tree = s->dyn_ltree;
+ s->l_desc.stat_desc = &static_l_desc;
+
+ s->d_desc.dyn_tree = s->dyn_dtree;
+ s->d_desc.stat_desc = &static_d_desc;
+
+ s->bl_desc.dyn_tree = s->bl_tree;
+ s->bl_desc.stat_desc = &static_bl_desc;
+
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ s->last_eob_len = 8; /* enough lookahead for inflate */
+#ifdef DEBUG
+ s->compressed_len = 0L;
+ s->bits_sent = 0L;
+#endif
+
+ /* Initialize the first block of the first file: */
+ init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+ deflate_state *s;
+{
+ int n; /* iterates over tree elements */
+
+ /* Initialize the trees. */
+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+ s->dyn_ltree[END_BLOCK].Freq = 1;
+ s->opt_len = s->static_len = 0L;
+ s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+ top = s->heap[SMALLEST]; \
+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+ pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+ (tree[n].Freq < tree[m].Freq || \
+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+ deflate_state *s;
+ ct_data *tree; /* the tree to restore */
+ int k; /* node to move down */
+{
+ int v = s->heap[k];
+ int j = k << 1; /* left son of k */
+ while (j <= s->heap_len) {
+ /* Set j to the smallest of the two sons: */
+ if (j < s->heap_len &&
+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+ j++;
+ }
+ /* Exit if v is smaller than both sons */
+ if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+ /* Exchange v with the smallest son */
+ s->heap[k] = s->heap[j]; k = j;
+
+ /* And continue down the tree, setting j to the left son of k */
+ j <<= 1;
+ }
+ s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ * above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ * array bl_count contains the frequencies for each bit length.
+ * The length opt_len is updated; static_len is also updated if stree is
+ * not null.
+ */
+local void gen_bitlen(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ int max_code = desc->max_code;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ const intf *extra = desc->stat_desc->extra_bits;
+ int base = desc->stat_desc->extra_base;
+ int max_length = desc->stat_desc->max_length;
+ int h; /* heap index */
+ int n, m; /* iterate over the tree elements */
+ int bits; /* bit length */
+ int xbits; /* extra bits */
+ ush f; /* frequency */
+ int overflow = 0; /* number of elements with bit length too large */
+
+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+ /* In a first pass, compute the optimal bit lengths (which may
+ * overflow in the case of the bit length tree).
+ */
+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+ n = s->heap[h];
+ bits = tree[tree[n].Dad].Len + 1;
+ if (bits > max_length) bits = max_length, overflow++;
+ tree[n].Len = (ush)bits;
+ /* We overwrite tree[n].Dad which is no longer needed */
+
+ if (n > max_code) continue; /* not a leaf node */
+
+ s->bl_count[bits]++;
+ xbits = 0;
+ if (n >= base) xbits = extra[n-base];
+ f = tree[n].Freq;
+ s->opt_len += (ulg)f * (bits + xbits);
+ if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+ }
+ if (overflow == 0) return;
+
+ Trace((stderr,"\nbit length overflow\n"));
+ /* This happens for example on obj2 and pic of the Calgary corpus */
+
+ /* Find the first bit length which could increase: */
+ do {
+ bits = max_length-1;
+ while (s->bl_count[bits] == 0) bits--;
+ s->bl_count[bits]--; /* move one leaf down the tree */
+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+ s->bl_count[max_length]--;
+ /* The brother of the overflow item also moves one step up,
+ * but this does not affect bl_count[max_length]
+ */
+ overflow -= 2;
+ } while (overflow > 0);
+
+ /* Now recompute all bit lengths, scanning in increasing frequency.
+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+ * lengths instead of fixing only the wrong ones. This idea is taken
+ * from 'ar' written by Haruhiko Okumura.)
+ */
+ for (bits = max_length; bits != 0; bits--) {
+ n = s->bl_count[bits];
+ while (n != 0) {
+ m = s->heap[--h];
+ if (m > max_code) continue;
+ if (tree[m].Len != (unsigned) bits) {
+ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+ s->opt_len += ((long)bits - (long)tree[m].Len)
+ *(long)tree[m].Freq;
+ tree[m].Len = (ush)bits;
+ }
+ n--;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ * zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+ ct_data *tree; /* the tree to decorate */
+ int max_code; /* largest code with non zero frequency */
+ ushf *bl_count; /* number of codes at each bit length */
+{
+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+ ush code = 0; /* running code value */
+ int bits; /* bit index */
+ int n; /* code index */
+
+ /* The distribution counts are first used to generate the code values
+ * without bit reversal.
+ */
+ for (bits = 1; bits <= MAX_BITS; bits++) {
+ next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+ }
+ /* Check that the bit counts in bl_count are consistent. The last code
+ * must be all ones.
+ */
+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+ "inconsistent bit counts");
+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+ for (n = 0; n <= max_code; n++) {
+ int len = tree[n].Len;
+ if (len == 0) continue;
+ /* Now reverse the bits */
+ tree[n].Code = bi_reverse(next_code[len]++, len);
+
+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+ }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ * and corresponding code. The length opt_len is updated; static_len is
+ * also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ int elems = desc->stat_desc->elems;
+ int n, m; /* iterate over heap elements */
+ int max_code = -1; /* largest code with non zero frequency */
+ int node; /* new node being created */
+
+ /* Construct the initial heap, with least frequent element in
+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+ * heap[0] is not used.
+ */
+ s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+ for (n = 0; n < elems; n++) {
+ if (tree[n].Freq != 0) {
+ s->heap[++(s->heap_len)] = max_code = n;
+ s->depth[n] = 0;
+ } else {
+ tree[n].Len = 0;
+ }
+ }
+
+ /* The pkzip format requires that at least one distance code exists,
+ * and that at least one bit should be sent even if there is only one
+ * possible code. So to avoid special checks later on we force at least
+ * two codes of non zero frequency.
+ */
+ while (s->heap_len < 2) {
+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+ tree[node].Freq = 1;
+ s->depth[node] = 0;
+ s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+ /* node is 0 or 1 so it does not have extra bits */
+ }
+ desc->max_code = max_code;
+
+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+ * establish sub-heaps of increasing lengths:
+ */
+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+ /* Construct the Huffman tree by repeatedly combining the least two
+ * frequent nodes.
+ */
+ node = elems; /* next internal node of the tree */
+ do {
+ pqremove(s, tree, n); /* n = node of least frequency */
+ m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+ s->heap[--(s->heap_max)] = m;
+
+ /* Create a new node father of n and m */
+ tree[node].Freq = tree[n].Freq + tree[m].Freq;
+ s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
+ s->depth[n] : s->depth[m]) + 1);
+ tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+ if (tree == s->bl_tree) {
+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+ }
+#endif
+ /* and insert the new node in the heap */
+ s->heap[SMALLEST] = node++;
+ pqdownheap(s, tree, SMALLEST);
+
+ } while (s->heap_len >= 2);
+
+ s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+ /* At this point, the fields freq and dad are set. We can now
+ * generate the bit lengths.
+ */
+ gen_bitlen(s, (tree_desc *)desc);
+
+ /* The field len is now set, we can generate the bit codes */
+ gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ if (nextlen == 0) max_count = 138, min_count = 3;
+ tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ s->bl_tree[curlen].Freq += count;
+ } else if (curlen != 0) {
+ if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+ s->bl_tree[REP_3_6].Freq++;
+ } else if (count <= 10) {
+ s->bl_tree[REPZ_3_10].Freq++;
+ } else {
+ s->bl_tree[REPZ_11_138].Freq++;
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ /* tree[max_code+1].Len = -1; */ /* guard already set */
+ if (nextlen == 0) max_count = 138, min_count = 3;
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+ } else if (curlen != 0) {
+ if (curlen != prevlen) {
+ send_code(s, curlen, s->bl_tree); count--;
+ }
+ Assert(count >= 3 && count <= 6, " 3_6?");
+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+ } else if (count <= 10) {
+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+ } else {
+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+ deflate_state *s;
+{
+ int max_blindex; /* index of last bit length code of non zero freq */
+
+ /* Determine the bit length frequencies for literal and distance trees */
+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+ /* Build the bit length tree: */
+ build_tree(s, (tree_desc *)(&(s->bl_desc)));
+ /* opt_len now includes the length of the tree representations, except
+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+ */
+
+ /* Determine the number of bit length codes to send. The pkzip format
+ * requires that at least 4 bit length codes be sent. (appnote.txt says
+ * 3 but the actual value used is 4.)
+ */
+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+ }
+ /* Update opt_len to include the bit length tree and counts */
+ s->opt_len += 3*(max_blindex+1) + 5+5+4;
+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+ s->opt_len, s->static_len));
+
+ return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+ deflate_state *s;
+ int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+ int rank; /* index in bl_order */
+
+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+ "too many codes");
+ Tracev((stderr, "\nbl counts: "));
+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+ send_bits(s, dcodes-1, 5);
+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
+ for (rank = 0; rank < blcodes; rank++) {
+ Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+ }
+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void _tr_stored_block(s, buf, stored_len, eof)
+ deflate_state *s;
+ charf *buf; /* input block */
+ ulg stored_len; /* length of input block */
+ int eof; /* true if this is the last block for a file */
+{
+ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
+#ifdef DEBUG
+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+ s->compressed_len += (stored_len + 4) << 3;
+#endif
+ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ * The current inflate code requires 9 bits of lookahead. If the
+ * last two codes for the previous block (real code plus EOB) were coded
+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+ * the last real code. In this case we send two empty static blocks instead
+ * of one. (There are no problems if the previous block is stored or fixed.)
+ * To simplify the code, we assume the worst case of last real code encoded
+ * on one bit only.
+ */
+void _tr_align(s)
+ deflate_state *s;
+{
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+ bi_flush(s);
+ /* Of the 10 bits for the empty block, we have already sent
+ * (10 - bi_valid) bits. The lookahead for the last real code (before
+ * the EOB of the previous block) was thus at least one plus the length
+ * of the EOB plus what we have just sent of the empty static block.
+ */
+ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+ s->compressed_len += 10L;
+#endif
+ bi_flush(s);
+ }
+ s->last_eob_len = 7;
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+void _tr_flush_block(s, buf, stored_len, eof)
+ deflate_state *s;
+ charf *buf; /* input block, or NULL if too old */
+ ulg stored_len; /* length of input block */
+ int eof; /* true if this is the last block for a file */
+{
+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+ int max_blindex = 0; /* index of last bit length code of non zero freq */
+
+ /* Build the Huffman trees unless a stored block is forced */
+ if (s->level > 0) {
+
+ /* Check if the file is ascii or binary */
+ if (s->strm->data_type == Z_UNKNOWN) set_data_type(s);
+
+ /* Construct the literal and distance trees */
+ build_tree(s, (tree_desc *)(&(s->l_desc)));
+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+
+ build_tree(s, (tree_desc *)(&(s->d_desc)));
+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+ /* At this point, opt_len and static_len are the total bit lengths of
+ * the compressed block data, excluding the tree representations.
+ */
+
+ /* Build the bit length tree for the above two trees, and get the index
+ * in bl_order of the last bit length code to send.
+ */
+ max_blindex = build_bl_tree(s);
+
+ /* Determine the best encoding. Compute the block lengths in bytes. */
+ opt_lenb = (s->opt_len+3+7)>>3;
+ static_lenb = (s->static_len+3+7)>>3;
+
+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+ s->last_lit));
+
+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+ } else {
+ Assert(buf != (char*)0, "lost buf");
+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+ }
+
+#ifdef FORCE_STORED
+ if (buf != (char*)0) { /* force stored block */
+#else
+ if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+ /* 4: two words for the lengths */
+#endif
+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+ * Otherwise we can't have processed more than WSIZE input bytes since
+ * the last block flush, because compression would have been
+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+ * transform a block into a stored block.
+ */
+ _tr_stored_block(s, buf, stored_len, eof);
+
+#ifdef FORCE_STATIC
+ } else if (static_lenb >= 0) { /* force static trees */
+#else
+ } else if (static_lenb == opt_lenb) {
+#endif
+ send_bits(s, (STATIC_TREES<<1)+eof, 3);
+ compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+#ifdef DEBUG
+ s->compressed_len += 3 + s->static_len;
+#endif
+ } else {
+ send_bits(s, (DYN_TREES<<1)+eof, 3);
+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+ max_blindex+1);
+ compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+#ifdef DEBUG
+ s->compressed_len += 3 + s->opt_len;
+#endif
+ }
+ Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+ /* The above check is made mod 2^32, for files larger than 512 MB
+ * and uLong implemented on 32 bits.
+ */
+ init_block(s);
+
+ if (eof) {
+ bi_windup(s);
+#ifdef DEBUG
+ s->compressed_len += 7; /* align on byte boundary */
+#endif
+ }
+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+ s->compressed_len-7*eof));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int _tr_tally (s, dist, lc)
+ deflate_state *s;
+ unsigned dist; /* distance of matched string */
+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+ s->d_buf[s->last_lit] = (ush)dist;
+ s->l_buf[s->last_lit++] = (uch)lc;
+ if (dist == 0) {
+ /* lc is the unmatched char */
+ s->dyn_ltree[lc].Freq++;
+ } else {
+ s->matches++;
+ /* Here, lc is the match length - MIN_MATCH */
+ dist--; /* dist = match distance - 1 */
+ Assert((ush)dist < (ush)MAX_DIST(s) &&
+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
+
+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+ s->dyn_dtree[d_code(dist)].Freq++;
+ }
+
+#ifdef TRUNCATE_BLOCK
+ /* Try to guess if it is profitable to stop the current block here */
+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+ /* Compute an upper bound for the compressed length */
+ ulg out_length = (ulg)s->last_lit*8L;
+ ulg in_length = (ulg)((long)s->strstart - s->block_start);
+ int dcode;
+ for (dcode = 0; dcode < D_CODES; dcode++) {
+ out_length += (ulg)s->dyn_dtree[dcode].Freq *
+ (5L+extra_dbits[dcode]);
+ }
+ out_length >>= 3;
+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+ s->last_lit, in_length, out_length,
+ 100L - out_length*100L/in_length));
+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+ }
+#endif
+ return (s->last_lit == s->lit_bufsize-1);
+ /* We avoid equality with lit_bufsize because of wraparound at 64K
+ * on 16 bit machines and because stored blocks are restricted to
+ * 64K-1 bytes.
+ */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+ deflate_state *s;
+ ct_data *ltree; /* literal tree */
+ ct_data *dtree; /* distance tree */
+{
+ unsigned dist; /* distance of matched string */
+ int lc; /* match length or unmatched char (if dist == 0) */
+ unsigned lx = 0; /* running index in l_buf */
+ unsigned code; /* the code to send */
+ int extra; /* number of extra bits to send */
+
+ if (s->last_lit != 0) do {
+ dist = s->d_buf[lx];
+ lc = s->l_buf[lx++];
+ if (dist == 0) {
+ send_code(s, lc, ltree); /* send a literal byte */
+ Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+ } else {
+ /* Here, lc is the match length - MIN_MATCH */
+ code = _length_code[lc];
+ send_code(s, code+LITERALS+1, ltree); /* send the length code */
+ extra = extra_lbits[code];
+ if (extra != 0) {
+ lc -= base_length[code];
+ send_bits(s, lc, extra); /* send the extra length bits */
+ }
+ dist--; /* dist is now the match distance - 1 */
+ code = d_code(dist);
+ Assert (code < D_CODES, "bad d_code");
+
+ send_code(s, code, dtree); /* send the distance code */
+ extra = extra_dbits[code];
+ if (extra != 0) {
+ dist -= base_dist[code];
+ send_bits(s, dist, extra); /* send the extra distance bits */
+ }
+ } /* literal or match pair ? */
+
+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+ Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
+ "pendingBuf overflow");
+
+ } while (lx < s->last_lit);
+
+ send_code(s, END_BLOCK, ltree);
+ s->last_eob_len = ltree[END_BLOCK].Len;
+}
+
+/* ===========================================================================
+ * Set the data type to ASCII or BINARY, using a crude approximation:
+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
+ * IN assertion: the fields freq of dyn_ltree are set and the total of all
+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
+ */
+local void set_data_type(s)
+ deflate_state *s;
+{
+ int n = 0;
+ unsigned ascii_freq = 0;
+ unsigned bin_freq = 0;
+ while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
+ while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
+ while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
+ s->strm->data_type = bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII;
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+ unsigned code; /* the value to invert */
+ int len; /* its bit length */
+{
+ register unsigned res = 0;
+ do {
+ res |= code & 1;
+ code >>= 1, res <<= 1;
+ } while (--len > 0);
+ return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+ deflate_state *s;
+{
+ if (s->bi_valid == 16) {
+ put_short(s, s->bi_buf);
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ } else if (s->bi_valid >= 8) {
+ put_byte(s, (Byte)s->bi_buf);
+ s->bi_buf >>= 8;
+ s->bi_valid -= 8;
+ }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+ deflate_state *s;
+{
+ if (s->bi_valid > 8) {
+ put_short(s, s->bi_buf);
+ } else if (s->bi_valid > 0) {
+ put_byte(s, (Byte)s->bi_buf);
+ }
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+#ifdef DEBUG
+ s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+ deflate_state *s;
+ charf *buf; /* the input data */
+ unsigned len; /* its length */
+ int header; /* true if block header must be written */
+{
+ bi_windup(s); /* align on byte boundary */
+ s->last_eob_len = 8; /* enough lookahead for inflate */
+
+ if (header) {
+ put_short(s, (ush)len);
+ put_short(s, (ush)~len);
+#ifdef DEBUG
+ s->bits_sent += 2*16;
+#endif
+ }
+#ifdef DEBUG
+ s->bits_sent += (ulg)len<<3;
+#endif
+ while (len--) {
+ put_byte(s, *buf++);
+ }
+}
diff --git a/src/zlib/trees.h b/src/zlib/trees.h
new file mode 100644
index 000000000..72facf900
--- /dev/null
+++ b/src/zlib/trees.h
@@ -0,0 +1,128 @@
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
+{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
+{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
+{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
+{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
+{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
+{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
+{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
+{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
+{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
+{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
+{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
+{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
+{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
+{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
+{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
+{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
+{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
+{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
+{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
+{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
+{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
+{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
+{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
+{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
+{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
+{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
+{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
+{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
+{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
+{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
+{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
+{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
+{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
+{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
+{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
+{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
+{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
+{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
+{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
+{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
+{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
+{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
+{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
+{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
+{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
+{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
+{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
+{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
+{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
+{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
+{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
+{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
+{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
+{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
+{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
+{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
+{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch _dist_code[DIST_CODE_LEN] = {
+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
+ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
+ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
+};
+
diff --git a/src/zlib/zconf.h b/src/zlib/zconf.h
new file mode 100644
index 000000000..3c21403fc
--- /dev/null
+++ b/src/zlib/zconf.h
@@ -0,0 +1,326 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2004 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+# define deflateInit_ z_deflateInit_
+# define deflate z_deflate
+# define deflateEnd z_deflateEnd
+# define inflateInit_ z_inflateInit_
+# define inflate z_inflate
+# define inflateEnd z_inflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateCopy z_deflateCopy
+# define deflateReset z_deflateReset
+# define deflateParams z_deflateParams
+# define deflateBound z_deflateBound
+# define deflatePrime z_deflatePrime
+# define inflateInit2_ z_inflateInit2_
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateCopy z_inflateCopy
+# define inflateReset z_inflateReset
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# define uncompress z_uncompress
+# define adler32 z_adler32
+# define crc32 z_crc32
+# define get_crc_table z_get_crc_table
+# define zError z_zError
+
+# define Byte z_Byte
+# define uInt z_uInt
+# define uLong z_uLong
+# define Bytef z_Bytef
+# define charf z_charf
+# define intf z_intf
+# define uIntf z_uIntf
+# define uLongf z_uLongf
+# define voidpf z_voidpf
+# define voidp z_voidp
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+# define WIN32
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+# define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
+# include <sys/types.h> /* for off_t */
+# include <unistd.h> /* for SEEK_* and off_t */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# define z_off_t off_t
+#endif
+#ifndef SEEK_SET
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if defined(__OS400__)
+# define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+# define NO_vsnprintf
+# ifdef FAR
+# undef FAR
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+# pragma map(deflateInit_,"DEIN")
+# pragma map(deflateInit2_,"DEIN2")
+# pragma map(deflateEnd,"DEEND")
+# pragma map(deflateBound,"DEBND")
+# pragma map(inflateInit_,"ININ")
+# pragma map(inflateInit2_,"ININ2")
+# pragma map(inflateEnd,"INEND")
+# pragma map(inflateSync,"INSY")
+# pragma map(inflateSetDictionary,"INSEDI")
+# pragma map(compressBound,"CMBND")
+# pragma map(inflate_table,"INTABL")
+# pragma map(inflate_fast,"INFA")
+# pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/src/zlib/zlib.h b/src/zlib/zlib.h
new file mode 100644
index 000000000..b4ddd3439
--- /dev/null
+++ b/src/zlib/zlib.h
@@ -0,0 +1,1200 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.2.2, October 3rd, 2004
+
+ Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.2"
+#define ZLIB_VERNUM 0x1220
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed
+ data. This version of the library supports only one compression method
+ (deflation) but other algorithms will be added later and will have the same
+ stream interface.
+
+ Compression can be done in a single step if the buffers are large
+ enough (for example if an input file is mmap'ed), or can be done by
+ repeated calls of the compression function. In the latter case, the
+ application must provide more input and/or consume the output
+ (providing more output space) before each call.
+
+ The compressed data format used by default by the in-memory functions is
+ the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+ around a deflate stream, which is itself documented in RFC 1951.
+
+ The library also supports reading and writing files in gzip (.gz) format
+ with an interface similar to that of stdio using the functions that start
+ with "gz". The gzip format is different from the zlib format. gzip is a
+ gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+ This library can optionally read and write gzip streams in memory as well.
+
+ The zlib format was designed to be compact and fast for use in memory
+ and on communications channels. The gzip format was designed for single-
+ file compression on file systems, has a larger header than zlib to maintain
+ directory information, and uses a different, slower check method than zlib.
+
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never
+ crash even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total nb of input bytes read so far */
+
+ Bytef *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total nb of bytes output so far */
+
+ char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidpf opaque; /* private data object passed to zalloc and zfree */
+
+ int data_type; /* best guess about the data type: ascii or binary */
+ uLong adler; /* adler32 value of the uncompressed data */
+ uLong reserved; /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+ The application must update next_in and avail_in when avail_in has
+ dropped to zero. It must update next_out and avail_out when avail_out
+ has dropped to zero. The application must initialize zalloc, zfree and
+ opaque before calling the init function. All other fields are set by the
+ compression library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
+ thread safe.
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this
+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
+ have their offset normalized to zero. The default allocation function
+ provided by this library ensures this (see zutil.c). To reduce memory
+ requirements and avoid any allocation of 64K objects, at the expense of
+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or
+ progress reports. After compression, total_in holds the total size of
+ the uncompressed data and may be saved for use in the decompressor
+ (particularly if the decompressor wants to decompress everything in
+ a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+#define Z_BLOCK 5
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_RLE 3
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_ASCII 1
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+ /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is
+ not compatible with the zlib.h header file used by the application.
+ This check is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller.
+ If zalloc and zfree are set to Z_NULL, deflateInit updates them to
+ use default allocation functions.
+
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at
+ all (the input data is simply copied a block at a time).
+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and
+ compression (currently equivalent to level 6).
+
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+ with the version assumed by the caller (ZLIB_VERSION).
+ msg is set to null if there is no error message. deflateInit does not
+ perform any compression: this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+ deflate compresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce some
+ output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. deflate performs one or both of the
+ following actions:
+
+ - Compress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in and avail_in are updated and
+ processing will resume at this point for the next call of deflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
+ Forcing flush frequently degrades the compression ratio, so this parameter
+ should be set only when necessary (in interactive applications).
+ Some output may be provided even if flush is not set.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating avail_in or avail_out accordingly; avail_out
+ should never be zero before the call. The application can consume the
+ compressed output when it wants, for example when the output buffer is full
+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+ and with zero avail_out, it must be called again after making room in the
+ output buffer because there might be more output pending.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+ flushed to the output buffer and the output is aligned on a byte boundary, so
+ that the decompressor can get all input data available so far. (In particular
+ avail_in is zero after the call if enough output space has been provided
+ before the call.) Flushing may degrade compression for some compression
+ algorithms and so it should be used only when necessary.
+
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ the compression.
+
+ If deflate returns with avail_out == 0, this function must be called again
+ with the same value of the flush parameter and more output space (updated
+ avail_out), until the flush is complete (deflate returns with non-zero
+ avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+ avail_out is greater than six to avoid repeated flush markers due to
+ avail_out == 0 on return.
+
+ If the parameter flush is set to Z_FINISH, pending input is processed,
+ pending output is flushed and deflate returns with Z_STREAM_END if there
+ was enough output space; if deflate returns with Z_OK, this function must be
+ called again with Z_FINISH and more output space (updated avail_out) but no
+ more input data, until it returns with Z_STREAM_END or an error. After
+ deflate has returned Z_STREAM_END, the only possible operations on the
+ stream are deflateReset or deflateEnd.
+
+ Z_FINISH can be used immediately after deflateInit if all the compression
+ is to be done in a single step. In this case, avail_out must be at least
+ the value returned by deflateBound (see below). If deflate does not return
+ Z_STREAM_END, then it must be called again as described above.
+
+ deflate() sets strm->adler to the adler32 checksum of all input read
+ so far (that is, total_in bytes).
+
+ deflate() may update data_type if it can make a good guess about
+ the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
+ binary. This field is only for information purposes and does not affect
+ the compression algorithm in any manner.
+
+ deflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if all input has been
+ consumed and all output has been produced (only when flush is set to
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
+ (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
+ fatal, and deflate() can be called again with more input and more output
+ space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+ prematurely (some input or output was discarded). In the error case,
+ msg may be set but then points to a static string (which must not be
+ deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+ Initializes the internal stream state for decompression. The fields
+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
+ value depends on the compression method), inflateInit determines the
+ compression method from the zlib header and allocates all data structures
+ accordingly; otherwise the allocation will be deferred to the first call of
+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+ use default allocation functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller. msg is set to null if there is no error
+ message. inflateInit does not perform any decompression apart from reading
+ the zlib header if present: this will be done by inflate(). (So next_in and
+ avail_in may be modified, but next_out and avail_out are unchanged.)
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+ inflate decompresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. inflate performs one or both of the
+ following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing
+ will resume at this point for the next call of inflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there
+ is no more input data or no more space in the output buffer (see below
+ about the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating the next_* and avail_* values accordingly.
+ The application can consume the uncompressed output when it wants, for
+ example when the output buffer is full (avail_out == 0), or after each
+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+ must be called again after making room in the output buffer because there
+ might be more output pending.
+
+ The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
+ Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
+ output as possible to the output buffer. Z_BLOCK requests that inflate() stop
+ if and when it get to the next deflate block boundary. When decoding the zlib
+ or gzip format, this will cause inflate() to return immediately after the
+ header and before the first block. When doing a raw inflate, inflate() will
+ go ahead and process the first block, and will return when it gets to the end
+ of that block, or when it runs out of data.
+
+ The Z_BLOCK option assists in appending to or combining deflate streams.
+ Also to assist in this, on return inflate() will set strm->data_type to the
+ number of unused bits in the last byte taken from strm->next_in, plus 64
+ if inflate() is currently decoding the last block in the deflate stream,
+ plus 128 if inflate() returned immediately after decoding an end-of-block
+ code or decoding the complete header up to just before the first byte of the
+ deflate stream. The end-of-block will not be indicated until all of the
+ uncompressed data from that block has been written to strm->next_out. The
+ number of unused bits may in general be greater than seven, except when
+ bit 7 of data_type is set, in which case the number of unused bits will be
+ less than eight.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step
+ (a single call of inflate), the parameter flush should be set to
+ Z_FINISH. In this case all pending input is processed and all pending
+ output is flushed; avail_out must be large enough to hold all the
+ uncompressed data. (The size of the uncompressed data may have been saved
+ by the compressor for this purpose.) The next operation on this stream must
+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+ is never required, but can be used to inform inflate that a faster approach
+ may be used for the single inflate() call.
+
+ In this implementation, inflate() always flushes as much output as
+ possible to the output buffer, and always uses the faster approach on the
+ first call. So the only effect of the flush parameter in this implementation
+ is on the return value of inflate(), as noted below, or when it returns early
+ because Z_BLOCK is used.
+
+ If a preset dictionary is needed after this call (see inflateSetDictionary
+ below), inflate sets strm->adler to the adler32 checksum of the dictionary
+ chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+ strm->adler to the adler32 checksum of all output produced so far (that is,
+ total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+ below. At the end of the stream, inflate() checks that its computed adler32
+ checksum is equal to that saved by the compressor and returns Z_STREAM_END
+ only if the checksum is correct.
+
+ inflate() will decompress and check either zlib-wrapped or gzip-wrapped
+ deflate data. The header type is detected automatically. Any information
+ contained in the gzip header is not retained, so applications that need that
+ information should instead use raw inflate, see inflateInit2() below, or
+ inflateBack() and perform their own processing of the gzip header and
+ trailer.
+
+ inflate() returns Z_OK if some progress has been made (more input processed
+ or more output produced), Z_STREAM_END if the end of the compressed data has
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+ corrupted (input stream not conforming to the zlib format or incorrect check
+ value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+ if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
+ Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+ output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+ inflate() can be called again with more input and more output space to
+ continue decompressing. If Z_DATA_ERROR is returned, the application may then
+ call inflateSync() to look for a good compression block if a partial recovery
+ of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+ was inconsistent. In the error case, msg may be set but then points to a
+ static string (which must not be deallocated).
+*/
+
+ /* Advanced functions */
+
+/*
+ The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy));
+
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by
+ the caller.
+
+ The method parameter is the compression method. It must be Z_DEFLATED in
+ this version of the library.
+
+ The windowBits parameter is the base two logarithm of the window size
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
+ deflateInit is used instead.
+
+ windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+ determines the window size. deflate() will then generate raw deflate data
+ with no zlib header or trailer, and will not compute an adler32 check value.
+
+ windowBits can also be greater than 15 for optional gzip encoding. Add
+ 16 to windowBits to write a simple gzip header and trailer around the
+ compressed data instead of a zlib wrapper. The gzip header will have no
+ file name, no extra data, no comment, no modification time (set to zero),
+ no header crc, and the operating system will be set to 255 (unknown). If a
+ gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+ The memLevel parameter specifies how much memory should be allocated
+ for the internal compression state. memLevel=1 uses minimum memory but
+ is slow and reduces compression ratio; memLevel=9 uses maximum memory
+ for optimal speed. The default value is 8. See zconf.h for total memory
+ usage as a function of windowBits and memLevel.
+
+ The strategy parameter is used to tune the compression algorithm. Use the
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+ filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+ string match), or Z_RLE to limit match distances to one (run-length
+ encoding). Filtered data consists mostly of small values with a somewhat
+ random distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect of Z_FILTERED is to force more Huffman
+ coding and less string matching; it is somewhat intermediate between
+ Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
+ Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
+ parameter only affects the compression ratio but not the correctness of the
+ compressed output even if it is not set appropriately.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
+ method). msg is set to null if there is no error message. deflateInit2 does
+ not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the compression dictionary from the given byte sequence
+ without producing any compressed output. This function must be called
+ immediately after deflateInit, deflateInit2 or deflateReset, before any
+ call of deflate. The compressor and decompressor must use exactly the same
+ dictionary (see inflateSetDictionary).
+
+ The dictionary should consist of strings (byte sequences) that are likely
+ to be encountered later in the data to be compressed, with the most commonly
+ used strings preferably put towards the end of the dictionary. Using a
+ dictionary is most useful when the data to be compressed is short and can be
+ predicted with good accuracy; the data can then be compressed better than
+ with the default empty dictionary.
+
+ Depending on the size of the compression data structures selected by
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
+ discarded, for example if the dictionary is larger than the window size in
+ deflate or deflate2. Thus the strings most likely to be useful should be
+ put at the end of the dictionary, not at the front.
+
+ Upon return of this function, strm->adler is set to the adler32 value
+ of the dictionary; the decompressor may later use this value to determine
+ which dictionary has been used by the compressor. (The adler32 value
+ applies to the whole dictionary even if only a subset of the dictionary is
+ actually used by the compressor.) If a raw deflate was requested, then the
+ adler32 value is not computed and strm->adler is not set.
+
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+ parameter is invalid (such as NULL dictionary) or the stream state is
+ inconsistent (for example if deflate has already been called for this stream
+ or if the compression method is bsort). deflateSetDictionary does not
+ perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when several compression strategies will be
+ tried, for example when there are several ways of pre-processing the input
+ data with a filter. The streams that will be discarded should then be freed
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
+ compression state which can be quite large, so this strategy is slow and
+ can consume lots of memory.
+
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to deflateEnd followed by deflateInit,
+ but does not free and reallocate all the internal compression state.
+ The stream will keep the same compression level and any other attributes
+ that may have been set by deflateInit2.
+
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+ int level,
+ int strategy));
+/*
+ Dynamically update the compression level and compression strategy. The
+ interpretation of level and strategy is as in deflateInit2. This can be
+ used to switch between compression and straight copy of the input data, or
+ to switch to a different kind of input data requiring a different
+ strategy. If the compression level is changed, the input available so far
+ is compressed with the old level (and may be flushed); the new level will
+ take effect only at the next call of deflate().
+
+ Before the call of deflateParams, the stream state must be set as for
+ a call of deflate(), since the currently available input may have to
+ be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+ if strm->avail_out was zero.
+*/
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+ uLong sourceLen));
+/*
+ deflateBound() returns an upper bound on the compressed size after
+ deflation of sourceLen bytes. It must be called after deflateInit()
+ or deflateInit2(). This would be used to allocate an output buffer
+ for deflation in a single pass, and so would be called before deflate().
+*/
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ deflatePrime() inserts bits in the deflate output stream. The intent
+ is that this function is used to start off the deflate output with the
+ bits leftover from a previous deflate stream when appending to it. As such,
+ this function can only be used for raw deflate, and must be used before the
+ first deflate() call after a deflateInit2() or deflateReset(). bits must be
+ less than or equal to 16, and that many of the least significant bits of
+ value will be inserted in the output.
+
+ deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+ int windowBits));
+
+ This is another version of inflateInit with an extra parameter. The
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+ before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. windowBits must be greater than or equal to the windowBits value
+ provided to deflateInit2() while compressing, or it must be equal to 15 if
+ deflateInit2() was not used. If a compressed stream with a larger window
+ size is given as input, inflate() will return with the error code
+ Z_DATA_ERROR instead of trying to allocate a larger window.
+
+ windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+ determines the window size. inflate() will then process raw deflate data,
+ not looking for a zlib or gzip header, not generating a check value, and not
+ looking for any check values for comparison at the end of the stream. This
+ is for use with other formats that use the deflate compressed data format
+ such as zip. Those formats provide their own check values. If a custom
+ format is developed using the raw deflate format for compressed data, it is
+ recommended that a check value such as an adler32 or a crc32 be applied to
+ the uncompressed data as is done in the zlib, gzip, and zip formats. For
+ most applications, the zlib format should be used as is. Note that comments
+ above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+ windowBits can also be greater than 15 for optional gzip decoding. Add
+ 32 to windowBits to enable zlib and gzip decoding with automatic header
+ detection, or add 16 to decode only the gzip format (the zlib format will
+ return a Z_DATA_ERROR. If a gzip stream is being decoded, strm->adler is
+ a crc32 instead of an adler32.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
+ memLevel). msg is set to null if there is no error message. inflateInit2
+ does not perform any decompression apart from reading the zlib header if
+ present: this will be done by inflate(). (So next_in and avail_in may be
+ modified, but next_out and avail_out are unchanged.)
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the decompression dictionary from the given uncompressed byte
+ sequence. This function must be called immediately after a call of inflate
+ if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the adler32 value returned by this call of
+ inflate. The compressor and decompressor must use exactly the same
+ dictionary (see deflateSetDictionary).
+
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+ parameter is invalid (such as NULL dictionary) or the stream state is
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+ expected one (incorrect adler32 value). inflateSetDictionary does not
+ perform any decompression: this will be done by subsequent calls of
+ inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+ Skips invalid compressed data until a full flush point (see above the
+ description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+ if no more input was provided, Z_DATA_ERROR if no flush point has been found,
+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+ case, the application may save the current current value of total_in which
+ indicates where valid compressed data was found. In the error case, the
+ application may repeatedly call inflateSync, providing more input each time,
+ until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when randomly accessing a large stream. The
+ first pass through the stream can periodically record the inflate state,
+ allowing restarting inflate at those points when randomly accessing the
+ stream.
+
+ inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate all the internal decompression state.
+ The stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_stream FAR *strm, int windowBits,
+ unsigned char FAR *window));
+
+ Initialize the internal stream state for decompression using inflateBack()
+ calls. The fields zalloc, zfree and opaque in strm must be initialized
+ before the call. If zalloc and zfree are Z_NULL, then the default library-
+ derived memory allocation routines are used. windowBits is the base two
+ logarithm of the window size, in the range 8..15. window is a caller
+ supplied buffer of that size. Except for special applications where it is
+ assured that deflate was used with small window sizes, windowBits must be 15
+ and a 32K byte window must be supplied to be able to decompress general
+ deflate streams.
+
+ See inflateBack() for the usage of these routines.
+
+ inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+ the paramaters are invalid, Z_MEM_ERROR if the internal state could not
+ be allocated, or Z_VERSION_ERROR if the version of the library does not
+ match the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_stream FAR *strm,
+ in_func in, void FAR *in_desc,
+ out_func out, void FAR *out_desc));
+/*
+ inflateBack() does a raw inflate with a single call using a call-back
+ interface for input and output. This is more efficient than inflate() for
+ file i/o applications in that it avoids copying between the output and the
+ sliding window by simply making the window itself the output buffer. This
+ function trusts the application to not change the output buffer passed by
+ the output function, at least until inflateBack() returns.
+
+ inflateBackInit() must be called first to allocate the internal state
+ and to initialize the state with the user-provided window buffer.
+ inflateBack() may then be used multiple times to inflate a complete, raw
+ deflate stream with each call. inflateBackEnd() is then called to free
+ the allocated state.
+
+ A raw deflate stream is one with no zlib or gzip header or trailer.
+ This routine would normally be used in a utility that reads zip or gzip
+ files and writes out uncompressed files. The utility would decode the
+ header and process the trailer on its own, hence this routine expects
+ only the raw deflate stream to decompress. This is different from the
+ normal behavior of inflate(), which expects either a zlib or gzip header and
+ trailer around the deflate stream.
+
+ inflateBack() uses two subroutines supplied by the caller that are then
+ called by inflateBack() for input and output. inflateBack() calls those
+ routines until it reads a complete deflate stream and writes out all of the
+ uncompressed data, or until it encounters an error. The function's
+ parameters and return types are defined above in the in_func and out_func
+ typedefs. inflateBack() will call in(in_desc, &buf) which should return the
+ number of bytes of provided input, and a pointer to that input in buf. If
+ there is no input available, in() must return zero--buf is ignored in that
+ case--and inflateBack() will return a buffer error. inflateBack() will call
+ out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
+ should return zero on success, or non-zero on failure. If out() returns
+ non-zero, inflateBack() will return with an error. Neither in() nor out()
+ are permitted to change the contents of the window provided to
+ inflateBackInit(), which is also the buffer that out() uses to write from.
+ The length written by out() will be at most the window size. Any non-zero
+ amount of input may be provided by in().
+
+ For convenience, inflateBack() can be provided input on the first call by
+ setting strm->next_in and strm->avail_in. If that input is exhausted, then
+ in() will be called. Therefore strm->next_in must be initialized before
+ calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
+ immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
+ must also be initialized, and then if strm->avail_in is not zero, input will
+ initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+
+ The in_desc and out_desc parameters of inflateBack() is passed as the
+ first parameter of in() and out() respectively when they are called. These
+ descriptors can be optionally used to pass any information that the caller-
+ supplied in() and out() functions need to do their job.
+
+ On return, inflateBack() will set strm->next_in and strm->avail_in to
+ pass back any unused input that was provided by the last in() call. The
+ return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+ if in() or out() returned an error, Z_DATA_ERROR if there was a format
+ error in the deflate stream (in which case strm->msg is set to indicate the
+ nature of the error), or Z_STREAM_ERROR if the stream was not properly
+ initialized. In the case of Z_BUF_ERROR, an input or output error can be
+ distinguished using strm->next_in which will be Z_NULL only if in() returned
+ an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
+ out() returning non-zero. (in() will always be called before out(), so
+ strm->next_in is assured to be defined if out() returns non-zero.) Note
+ that inflateBack() cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_stream FAR *strm));
+/*
+ All memory allocated by inflateBackInit() is freed.
+
+ inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+ state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+ Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+ 1.0: size of uInt
+ 3.2: size of uLong
+ 5.4: size of voidpf (pointer)
+ 7.6: size of z_off_t
+
+ Compiler, assembler, and debug options:
+ 8: DEBUG
+ 9: ASMV or ASMINF -- use ASM code
+ 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+ 11: 0 (reserved)
+
+ One-time table building (smaller code, but not thread-safe if true):
+ 12: BUILDFIXED -- build static block decoding tables when needed
+ 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+ 14,15: 0 (reserved)
+
+ Library content (indicates missing functionality):
+ 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+ deflate code when not needed)
+ 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+ and decode gzip streams (to avoid linking crc code)
+ 18-19: 0 (reserved)
+
+ Operation variations (changes in library functionality):
+ 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+ 21: FASTEST -- deflate algorithm with only one, lowest compression level
+ 22,23: 0 (reserved)
+
+ The sprintf variant used by gzprintf (zero is best):
+ 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+ 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+ 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+ Remainder:
+ 27-31: 0 (reserved)
+ */
+
+
+ /* utility functions */
+
+/*
+ The following utility functions are implemented on top of the
+ basic stream-oriented functions. To simplify the interface, some
+ default options are assumed (compression level and memory usage,
+ standard memory allocation functions). The source code of these
+ utility functions can easily be modified if you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Compresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be at least the value returned
+ by compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+ This function can be used to compress a whole file at once if the
+ input file is mmap'ed.
+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level));
+/*
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+ compressBound() returns an upper bound on the compressed size after
+ compress() or compress2() on sourceLen bytes. It would be used before
+ a compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be large enough to hold the
+ entire uncompressed data. (The size of the uncompressed data must have
+ been saved previously by the compressor and transmitted to the decompressor
+ by some mechanism outside the scope of this compression library.)
+ Upon exit, destLen is the actual size of the compressed buffer.
+ This function can be used to decompress a whole file at once if the
+ input file is mmap'ed.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
+*/
+
+
+typedef voidp gzFile;
+
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+/*
+ Opens a gzip (.gz) file for reading or writing. The mode parameter
+ is as in fopen ("rb" or "wb") but can also include a compression level
+ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
+ Huffman only compression as in "wb1h", or 'R' for run-length encoding
+ as in "wb1R". (See the description of deflateInit2 for more information
+ about the strategy parameter.)
+
+ gzopen can be used to read a file which is not in gzip format; in this
+ case gzread will directly read from the file without decompression.
+
+ gzopen returns NULL if the file could not be opened or if there was
+ insufficient memory to allocate the (de)compression state; errno
+ can be checked to distinguish the two cases (if errno is zero, the
+ zlib error is Z_MEM_ERROR). */
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+ gzdopen() associates a gzFile with the file descriptor fd. File
+ descriptors are obtained from calls like open, dup, creat, pipe or
+ fileno (in the file has been previously opened with fopen).
+ The mode parameter is as in gzopen.
+ The next call of gzclose on the returned gzFile will also close the
+ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
+ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
+ gzdopen returns NULL if there was insufficient memory to allocate
+ the (de)compression state.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+ Dynamically update the compression level or strategy. See the description
+ of deflateInit2 for the meaning of these parameters.
+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+ opened for writing.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+ Reads the given number of uncompressed bytes from the compressed file.
+ If the input file was not in gzip format, gzread copies the given number
+ of bytes into the buffer.
+ gzread returns the number of uncompressed bytes actually read (0 for
+ end of file, -1 for error). */
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+ voidpc buf, unsigned len));
+/*
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of uncompressed bytes actually written
+ (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
+/*
+ Converts, formats, and writes the args to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written (0 in case of error). The number of
+ uncompressed bytes written is limited to 4095. The caller should assure that
+ this limit is not exceeded. If it is exceeded, then gzprintf() will return
+ return an error (0) with nothing written. In this case, there may also be a
+ buffer overflow with unpredictable consequences, which is possible only if
+ zlib was compiled with the insecure functions sprintf() or vsprintf()
+ because the secure snprintf() or vsnprintf() functions were not available.
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+ Reads bytes from the compressed file until len-1 characters are read, or
+ a newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. The string is then terminated with a null
+ character.
+ gzgets returns buf, or Z_NULL in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+ Writes c, converted to an unsigned char, into the compressed file.
+ gzputc returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+ Reads one byte from the compressed file. gzgetc returns this byte
+ or -1 in case of end of file or error.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+ Push one character back onto the stream to be read again later.
+ Only one character of push-back is allowed. gzungetc() returns the
+ character pushed, or -1 on failure. gzungetc() will fail if a
+ character has been pushed but not read yet, or if c is -1. The pushed
+ character will be discarded if the stream is repositioned with gzseek()
+ or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+ Flushes all pending output into the compressed file. The parameter
+ flush is as in the deflate() function. The return value is the zlib
+ error number (see function gzerror below). gzflush returns Z_OK if
+ the flush parameter is Z_FINISH and all output could be flushed.
+ gzflush should be called only when strictly necessary because it can
+ degrade compression.
+*/
+
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+/*
+ Sets the starting position for the next gzread or gzwrite on the
+ given compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
+ the value SEEK_END is not supported.
+ If the file is opened for reading, this function is emulated but can be
+ extremely slow. If the file is opened for writing, only forward seeks are
+ supported; gzseek then compresses a sequence of zeroes up to the new
+ starting position.
+
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error, in
+ particular if the file is opened for writing and the new starting position
+ would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
+/*
+ Rewinds the given file. This function is supported only for reading.
+
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
+/*
+ Returns the starting position for the next gzread or gzwrite on the
+ given compressed file. This position represents a number of bytes in the
+ uncompressed data stream.
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+ Returns 1 when EOF has previously been detected reading the given
+ input stream, otherwise zero.
+*/
+
+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
+/*
+ Flushes all pending output if necessary, closes the compressed file
+ and deallocates all the (de)compression state. The return value is the zlib
+ error number (see function gzerror below).
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+ Returns the error message for the last error which occurred on the
+ given compressed file. errnum is set to zlib error number. If an
+ error occurred in the file system and not in the compression library,
+ errnum is set to Z_ERRNO and the application may consult errno
+ to get the exact error code.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+ Clears the error and end-of-file flags for file. This is analogous to the
+ clearerr() function in stdio. This is useful for continuing to read a gzip
+ file that is being written concurrently.
+*/
+
+ /* checksum functions */
+
+/*
+ These functions are not related to compression but are exported
+ anyway because they might be useful in applications using the
+ compression library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is NULL, this function returns
+ the required initial value for the checksum.
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster. Usage example:
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+/*
+ Update a running crc with the bytes buf[0..len-1] and return the updated
+ crc. If buf is NULL, this function returns the required initial value
+ for the crc. Pre- and post-conditioning (one's complement) is performed
+ within this function so it shouldn't be done by the application.
+ Usage example:
+
+ uLong crc = crc32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = crc32(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+*/
+
+
+ /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits,
+ unsigned char FAR *window,
+ const char *version,
+ int stream_size));
+#define deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+ inflateBackInit_((strm), (windowBits), (window), \
+ ZLIB_VERSION, sizeof(z_stream))
+
+
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+ struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+ZEXTERN const char * ZEXPORT zError OF((int));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/src/zlib/zutil.c b/src/zlib/zutil.c
new file mode 100644
index 000000000..0ef4f99f5
--- /dev/null
+++ b/src/zlib/zutil.c
@@ -0,0 +1,319 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+#ifndef NO_DUMMY_DECL
+struct internal_state {int dummy;}; /* for buggy compilers */
+#endif
+
+#ifndef STDC
+extern void exit OF((int));
+#endif
+
+const char * const z_errmsg[10] = {
+"need dictionary", /* Z_NEED_DICT 2 */
+"stream end", /* Z_STREAM_END 1 */
+"", /* Z_OK 0 */
+"file error", /* Z_ERRNO (-1) */
+"stream error", /* Z_STREAM_ERROR (-2) */
+"data error", /* Z_DATA_ERROR (-3) */
+"insufficient memory", /* Z_MEM_ERROR (-4) */
+"buffer error", /* Z_BUF_ERROR (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion()
+{
+ return ZLIB_VERSION;
+}
+
+uLong ZEXPORT zlibCompileFlags()
+{
+ uLong flags;
+
+ flags = 0;
+ switch (sizeof(uInt)) {
+ case 2: break;
+ case 4: flags += 1; break;
+ case 8: flags += 2; break;
+ default: flags += 3;
+ }
+ switch (sizeof(uLong)) {
+ case 2: break;
+ case 4: flags += 1 << 2; break;
+ case 8: flags += 2 << 2; break;
+ default: flags += 3 << 2;
+ }
+ switch (sizeof(voidpf)) {
+ case 2: break;
+ case 4: flags += 1 << 4; break;
+ case 8: flags += 2 << 4; break;
+ default: flags += 3 << 4;
+ }
+ switch (sizeof(z_off_t)) {
+ case 2: break;
+ case 4: flags += 1 << 6; break;
+ case 8: flags += 2 << 6; break;
+ default: flags += 3 << 6;
+ }
+#ifdef DEBUG
+ flags += 1 << 8;
+#endif
+#if defined(ASMV) || defined(ASMINF)
+ flags += 1 << 9;
+#endif
+#ifdef ZLIB_WINAPI
+ flags += 1 << 10;
+#endif
+#ifdef BUILDFIXED
+ flags += 1 << 12;
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+ flags += 1 << 13;
+#endif
+#ifdef NO_GZCOMPRESS
+ flags += 1 << 16;
+#endif
+#ifdef NO_GZIP
+ flags += 1 << 17;
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+ flags += 1 << 20;
+#endif
+#ifdef FASTEST
+ flags += 1 << 21;
+#endif
+#ifdef STDC
+# ifdef NO_vsnprintf
+ flags += 1 << 25;
+# ifdef HAS_vsprintf_void
+ flags += 1 << 26;
+# endif
+# else
+# ifdef HAS_vsnprintf_void
+ flags += 1 << 26;
+# endif
+# endif
+#else
+ flags += 1 << 24;
+# ifdef NO_snprintf
+ flags += 1 << 25;
+# ifdef HAS_sprintf_void
+ flags += 1 << 26;
+# endif
+# else
+# ifdef HAS_snprintf_void
+ flags += 1 << 26;
+# endif
+# endif
+#endif
+ return flags;
+}
+
+#ifdef DEBUG
+
+# ifndef verbose
+# define verbose 0
+# endif
+int z_verbose = verbose;
+
+void z_error (m)
+ char *m;
+{
+ fprintf(stderr, "%s\n", m);
+ exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+ int err;
+{
+ return ERR_MSG(err);
+}
+
+#if defined(_WIN32_WCE)
+ /* does not exist on WCE */
+ int errno = 0;
+#endif
+
+#ifndef HAVE_MEMCPY
+
+void zmemcpy(dest, source, len)
+ Bytef* dest;
+ const Bytef* source;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = *source++; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+
+int zmemcmp(s1, s2, len)
+ const Bytef* s1;
+ const Bytef* s2;
+ uInt len;
+{
+ uInt j;
+
+ for (j = 0; j < len; j++) {
+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+ }
+ return 0;
+}
+
+void zmemzero(dest, len)
+ Bytef* dest;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = 0; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+#endif
+
+
+#ifdef SYS16BIT
+
+#ifdef __TURBOC__
+/* Turbo C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+ voidpf org_ptr;
+ voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ voidpf buf = opaque; /* just to make some compilers happy */
+ ulg bsize = (ulg)items*size;
+
+ /* If we allocate less than 65520 bytes, we assume that farmalloc
+ * will return a usable pointer which doesn't have to be normalized.
+ */
+ if (bsize < 65520L) {
+ buf = farmalloc(bsize);
+ if (*(ush*)&buf != 0) return buf;
+ } else {
+ buf = farmalloc(bsize + 16L);
+ }
+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+ table[next_ptr].org_ptr = buf;
+
+ /* Normalize the pointer to seg:0 */
+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+ *(ush*)&buf = 0;
+ table[next_ptr++].new_ptr = buf;
+ return buf;
+}
+
+void zcfree (voidpf opaque, voidpf ptr)
+{
+ int n;
+ if (*(ush*)&ptr != 0) { /* object < 64K */
+ farfree(ptr);
+ return;
+ }
+ /* Find the original pointer */
+ for (n = 0; n < next_ptr; n++) {
+ if (ptr != table[n].new_ptr) continue;
+
+ farfree(table[n].org_ptr);
+ while (++n < next_ptr) {
+ table[n-1] = table[n];
+ }
+ next_ptr--;
+ return;
+ }
+ ptr = opaque; /* just to make some compilers happy */
+ Assert(0, "zcfree: ptr not found");
+}
+
+#endif /* __TURBOC__ */
+
+
+#ifdef M_I86
+/* Microsoft C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+# define _halloc halloc
+# define _hfree hfree
+#endif
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ return _halloc((long)items, size);
+}
+
+void zcfree (voidpf opaque, voidpf ptr)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ _hfree(ptr);
+}
+
+#endif /* M_I86 */
+
+#endif /* SYS16BIT */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp malloc OF((uInt size));
+extern voidp calloc OF((uInt items, uInt size));
+extern void free OF((voidpf ptr));
+#endif
+
+voidpf zcalloc (opaque, items, size)
+ voidpf opaque;
+ unsigned items;
+ unsigned size;
+{
+ if (opaque) items += size - size; /* make compiler happy */
+ return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+ (voidpf)calloc(items, size);
+}
+
+void zcfree (opaque, ptr)
+ voidpf opaque;
+ voidpf ptr;
+{
+ free(ptr);
+ if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
diff --git a/src/zlib/zutil.h b/src/zlib/zutil.h
new file mode 100644
index 000000000..7b42edcaa
--- /dev/null
+++ b/src/zlib/zutil.h
@@ -0,0 +1,263 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+#ifdef STDC
+# include <stddef.h>
+# include <string.h>
+# include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+ extern int errno;
+#else
+# include <errno.h>
+#endif
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long ulg;
+
+extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+ return (strm->msg = (char*)ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+ /* common constants */
+
+#ifndef DEF_WBITS
+# define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES 2
+/* The three kinds of block type */
+
+#define MIN_MATCH 3
+#define MAX_MATCH 258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+ /* target dependencies */
+
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
+# define OS_CODE 0x00
+# if defined(__TURBOC__) || defined(__BORLANDC__)
+# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+ /* Allow compilation with ANSI keywords only enabled */
+ void _Cdecl farfree( void *block );
+ void *_Cdecl farmalloc( unsigned long nbytes );
+# else
+# include <alloc.h>
+# endif
+# else /* MSC or DJGPP */
+# include <malloc.h>
+# endif
+#endif
+
+#ifdef AMIGA
+# define OS_CODE 0x01
+#endif
+
+#if defined(VAXC) || defined(VMS)
+# define OS_CODE 0x02
+# define F_OPEN(name, mode) \
+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#if defined(ATARI) || defined(atarist)
+# define OS_CODE 0x05
+#endif
+
+#ifdef OS2
+# define OS_CODE 0x06
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+# define OS_CODE 0x07
+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include <unix.h> /* for fdopen */
+# else
+# ifndef fdopen
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# endif
+# endif
+#endif
+
+#ifdef TOPS20
+# define OS_CODE 0x0a
+#endif
+
+#ifdef WIN32
+# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
+# define OS_CODE 0x0b
+# endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+# define OS_CODE 0x0f
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600))
+# if defined(_WIN32_WCE)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# ifndef _PTRDIFF_T_DEFINED
+ typedef int ptrdiff_t;
+# define _PTRDIFF_T_DEFINED
+# endif
+# else
+# define fdopen(fd,type) _fdopen(fd,type)
+# endif
+#endif
+
+ /* common defaults */
+
+#ifndef OS_CODE
+# define OS_CODE 0x03 /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+# define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+ /* functions */
+
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+#if defined(__CYGWIN__)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+#ifndef HAVE_VSNPRINTF
+# ifdef MSDOS
+ /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+ but for now we just assume it doesn't. */
+# define NO_vsnprintf
+# endif
+# ifdef __TURBOC__
+# define NO_vsnprintf
+# endif
+# ifdef WIN32
+ /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+# if !defined(vsnprintf) && !defined(NO_vsnprintf)
+# define vsnprintf _vsnprintf
+# endif
+# endif
+# ifdef __SASC
+# define NO_vsnprintf
+# endif
+#endif
+#ifdef VMS
+# define NO_vsnprintf
+#endif
+
+#ifdef HAVE_STRERROR
+# ifndef VMS
+ extern char *strerror OF((int));
+# endif
+# define zstrerror(errnum) strerror(errnum)
+#else
+# define zstrerror(errnum) ""
+#endif
+
+#if defined(pyr)
+# define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+ * You may have to use the same strategy for Borland C (untested).
+ * The __SC__ check is for Symantec.
+ */
+# define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+# define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+# define zmemcpy _fmemcpy
+# define zmemcmp _fmemcmp
+# define zmemzero(dest, len) _fmemset(dest, 0, len)
+# else
+# define zmemcpy memcpy
+# define zmemcmp memcmp
+# define zmemzero(dest, len) memset(dest, 0, len)
+# endif
+#else
+ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+ extern void zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+# include <stdio.h>
+ extern int z_verbose;
+ extern void z_error OF((char *m));
+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+
+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
+void zcfree OF((voidpf opaque, voidpf ptr));
+
+#define ZALLOC(strm, items, size) \
+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+#endif /* ZUTIL_H */